From 0801e2f424d741b73f844f2f2018f818be0528b9 Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 12 Aug 2025 12:34:55 +0000 Subject: [PATCH 001/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 60887011..e8c115ca 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v15.74.0 +ERPNEXT_VERSION=v15.75.0 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index 515fa983..a18afa8e 100644 --- a/pwd.yml +++ b/pwd.yml @@ -2,7 +2,7 @@ version: "3" services: backend: - image: frappe/erpnext:v15.74.0 + image: frappe/erpnext:v15.75.0 networks: - frappe_network deploy: @@ -18,7 +18,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v15.74.0 + image: frappe/erpnext:v15.75.0 networks: - frappe_network deploy: @@ -47,7 +47,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v15.74.0 + image: frappe/erpnext:v15.75.0 networks: - frappe_network deploy: @@ -102,7 +102,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v15.74.0 + image: frappe/erpnext:v15.75.0 networks: - frappe_network depends_on: @@ -128,7 +128,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v15.74.0 + image: frappe/erpnext:v15.75.0 networks: - frappe_network deploy: @@ -144,7 +144,7 @@ services: - logs:/home/frappe/frappe-bench/logs queue-short: - image: frappe/erpnext:v15.74.0 + image: frappe/erpnext:v15.75.0 networks: - frappe_network deploy: @@ -178,7 +178,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v15.74.0 + image: frappe/erpnext:v15.75.0 networks: - frappe_network deploy: @@ -192,7 +192,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v15.74.0 + image: frappe/erpnext:v15.75.0 networks: - frappe_network deploy: From 443fc5f04ddcc73d0248a403f9ad0481129dff9d Mon Sep 17 00:00:00 2001 From: github-actions Date: Thu, 14 Aug 2025 06:36:11 +0000 Subject: [PATCH 002/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index e8c115ca..1084d777 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v15.75.0 +ERPNEXT_VERSION=v15.75.1 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index a18afa8e..8fd88c9a 100644 --- a/pwd.yml +++ b/pwd.yml @@ -2,7 +2,7 @@ version: "3" services: backend: - image: frappe/erpnext:v15.75.0 + image: frappe/erpnext:v15.75.1 networks: - frappe_network deploy: @@ -18,7 +18,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v15.75.0 + image: frappe/erpnext:v15.75.1 networks: - frappe_network deploy: @@ -47,7 +47,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v15.75.0 + image: frappe/erpnext:v15.75.1 networks: - frappe_network deploy: @@ -102,7 +102,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v15.75.0 + image: frappe/erpnext:v15.75.1 networks: - frappe_network depends_on: @@ -128,7 +128,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v15.75.0 + image: frappe/erpnext:v15.75.1 networks: - frappe_network deploy: @@ -144,7 +144,7 @@ services: - logs:/home/frappe/frappe-bench/logs queue-short: - image: frappe/erpnext:v15.75.0 + image: frappe/erpnext:v15.75.1 networks: - frappe_network deploy: @@ -178,7 +178,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v15.75.0 + image: frappe/erpnext:v15.75.1 networks: - frappe_network deploy: @@ -192,7 +192,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v15.75.0 + image: frappe/erpnext:v15.75.1 networks: - frappe_network deploy: From 86371d37fed7902d87840ff38649b45168e4ed2a Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 19 Aug 2025 12:26:04 +0000 Subject: [PATCH 003/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 1084d777..747e23ac 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v15.75.1 +ERPNEXT_VERSION=v15.76.0 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index 8fd88c9a..76fb7f46 100644 --- a/pwd.yml +++ b/pwd.yml @@ -2,7 +2,7 @@ version: "3" services: backend: - image: frappe/erpnext:v15.75.1 + image: frappe/erpnext:v15.76.0 networks: - frappe_network deploy: @@ -18,7 +18,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v15.75.1 + image: frappe/erpnext:v15.76.0 networks: - frappe_network deploy: @@ -47,7 +47,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v15.75.1 + image: frappe/erpnext:v15.76.0 networks: - frappe_network deploy: @@ -102,7 +102,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v15.75.1 + image: frappe/erpnext:v15.76.0 networks: - frappe_network depends_on: @@ -128,7 +128,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v15.75.1 + image: frappe/erpnext:v15.76.0 networks: - frappe_network deploy: @@ -144,7 +144,7 @@ services: - logs:/home/frappe/frappe-bench/logs queue-short: - image: frappe/erpnext:v15.75.1 + image: frappe/erpnext:v15.76.0 networks: - frappe_network deploy: @@ -178,7 +178,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v15.75.1 + image: frappe/erpnext:v15.76.0 networks: - frappe_network deploy: @@ -192,7 +192,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v15.75.1 + image: frappe/erpnext:v15.76.0 networks: - frappe_network deploy: From 821143d2e45ec32ae1d2e219ecbeee5ba8af340b Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 26 Aug 2025 12:08:02 +0000 Subject: [PATCH 004/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 747e23ac..5507b993 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v15.76.0 +ERPNEXT_VERSION=v15.77.0 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index 76fb7f46..ea4746d0 100644 --- a/pwd.yml +++ b/pwd.yml @@ -2,7 +2,7 @@ version: "3" services: backend: - image: frappe/erpnext:v15.76.0 + image: frappe/erpnext:v15.77.0 networks: - frappe_network deploy: @@ -18,7 +18,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v15.76.0 + image: frappe/erpnext:v15.77.0 networks: - frappe_network deploy: @@ -47,7 +47,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v15.76.0 + image: frappe/erpnext:v15.77.0 networks: - frappe_network deploy: @@ -102,7 +102,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v15.76.0 + image: frappe/erpnext:v15.77.0 networks: - frappe_network depends_on: @@ -128,7 +128,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v15.76.0 + image: frappe/erpnext:v15.77.0 networks: - frappe_network deploy: @@ -144,7 +144,7 @@ services: - logs:/home/frappe/frappe-bench/logs queue-short: - image: frappe/erpnext:v15.76.0 + image: frappe/erpnext:v15.77.0 networks: - frappe_network deploy: @@ -178,7 +178,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v15.76.0 + image: frappe/erpnext:v15.77.0 networks: - frappe_network deploy: @@ -192,7 +192,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v15.76.0 + image: frappe/erpnext:v15.77.0 networks: - frappe_network deploy: From fb8a5e133bf022cd2f08338167a383e9db368ecb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 29 Aug 2025 05:36:27 +0530 Subject: [PATCH 005/279] chore(deps): bump actions/checkout from 4 to 5 (#1677) Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '5' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build_bench.yml | 2 +- .github/workflows/build_stable.yml | 2 +- .github/workflows/docker-build-push.yml | 2 +- .github/workflows/lint.yml | 2 +- .github/workflows/pre-commit-autoupdate.yml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build_bench.yml b/.github/workflows/build_bench.yml index e5a61141..bdabd476 100644 --- a/.github/workflows/build_bench.yml +++ b/.github/workflows/build_bench.yml @@ -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 diff --git a/.github/workflows/build_stable.yml b/.github/workflows/build_stable.yml index 275c22ac..cd9e6139 100644 --- a/.github/workflows/build_stable.yml +++ b/.github/workflows/build_stable.yml @@ -62,7 +62,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Setup Python uses: actions/setup-python@v5 diff --git a/.github/workflows/docker-build-push.yml b/.github/workflows/docker-build-push.yml index 3694ec00..01c50741 100644 --- a/.github/workflows/docker-build-push.yml +++ b/.github/workflows/docker-build-push.yml @@ -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 diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index ce4ab6ee..4879c337 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Setup Python uses: actions/setup-python@v5 diff --git a/.github/workflows/pre-commit-autoupdate.yml b/.github/workflows/pre-commit-autoupdate.yml index 5612c735..29a5b5af 100644 --- a/.github/workflows/pre-commit-autoupdate.yml +++ b/.github/workflows/pre-commit-autoupdate.yml @@ -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 From 8782363a882c0889a13e0cc771a0ee7ff572de9e Mon Sep 17 00:00:00 2001 From: Jared Nay Date: Thu, 28 Aug 2025 20:06:45 -0400 Subject: [PATCH 006/279] Add extra detail to line 33 of README.md to improve user accessibility. (#1675) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 39f843eb..32edc8e4 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ Then run: `docker compose -f pwd.yml up -d` ### To run on ARM64 architecture follow this instructions -After cloning the repo run this command to build multi-architecture images specifically for ARM64. +After you clone the repo and `cd frappe_docker`, run this command to build multi-architecture images specifically for ARM64. `docker buildx bake --no-cache --set "*.platform=linux/arm64"` From e642a804ca9d0d096e514becca91e7ae0a2fada7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 29 Aug 2025 05:37:31 +0530 Subject: [PATCH 007/279] chore(deps): bump docker/bake-action from 6.8.0 to 6.9.0 (#1681) Bumps [docker/bake-action](https://github.com/docker/bake-action) from 6.8.0 to 6.9.0. - [Release notes](https://github.com/docker/bake-action/releases) - [Commits](https://github.com/docker/bake-action/compare/v6.8.0...v6.9.0) --- updated-dependencies: - dependency-name: docker/bake-action dependency-version: 6.9.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build_bench.yml | 4 ++-- .github/workflows/docker-build-push.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build_bench.yml b/.github/workflows/build_bench.yml index bdabd476..1835f1c3 100644 --- a/.github/workflows/build_bench.yml +++ b/.github/workflows/build_bench.yml @@ -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 diff --git a/.github/workflows/docker-build-push.yml b/.github/workflows/docker-build-push.yml index 01c50741..2323cba7 100644 --- a/.github/workflows/docker-build-push.yml +++ b/.github/workflows/docker-build-push.yml @@ -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 @@ -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" From e66f6b5042062b77b5fe0b31ce43127f1beb51c2 Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 2 Sep 2025 14:22:03 +0000 Subject: [PATCH 008/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 5507b993..e34d73cb 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v15.77.0 +ERPNEXT_VERSION=v15.78.0 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index ea4746d0..582603e5 100644 --- a/pwd.yml +++ b/pwd.yml @@ -2,7 +2,7 @@ version: "3" services: backend: - image: frappe/erpnext:v15.77.0 + image: frappe/erpnext:v15.78.0 networks: - frappe_network deploy: @@ -18,7 +18,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v15.77.0 + image: frappe/erpnext:v15.78.0 networks: - frappe_network deploy: @@ -47,7 +47,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v15.77.0 + image: frappe/erpnext:v15.78.0 networks: - frappe_network deploy: @@ -102,7 +102,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v15.77.0 + image: frappe/erpnext:v15.78.0 networks: - frappe_network depends_on: @@ -128,7 +128,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v15.77.0 + image: frappe/erpnext:v15.78.0 networks: - frappe_network deploy: @@ -144,7 +144,7 @@ services: - logs:/home/frappe/frappe-bench/logs queue-short: - image: frappe/erpnext:v15.77.0 + image: frappe/erpnext:v15.78.0 networks: - frappe_network deploy: @@ -178,7 +178,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v15.77.0 + image: frappe/erpnext:v15.78.0 networks: - frappe_network deploy: @@ -192,7 +192,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v15.77.0 + image: frappe/erpnext:v15.78.0 networks: - frappe_network deploy: From 06fbff626e55871eb2bff50a3a356478630f37e6 Mon Sep 17 00:00:00 2001 From: github-actions Date: Thu, 4 Sep 2025 15:11:02 +0000 Subject: [PATCH 009/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index e34d73cb..378a6324 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v15.78.0 +ERPNEXT_VERSION=v15.78.1 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index 582603e5..c75ec63e 100644 --- a/pwd.yml +++ b/pwd.yml @@ -2,7 +2,7 @@ version: "3" services: backend: - image: frappe/erpnext:v15.78.0 + image: frappe/erpnext:v15.78.1 networks: - frappe_network deploy: @@ -18,7 +18,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v15.78.0 + image: frappe/erpnext:v15.78.1 networks: - frappe_network deploy: @@ -47,7 +47,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v15.78.0 + image: frappe/erpnext:v15.78.1 networks: - frappe_network deploy: @@ -102,7 +102,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v15.78.0 + image: frappe/erpnext:v15.78.1 networks: - frappe_network depends_on: @@ -128,7 +128,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v15.78.0 + image: frappe/erpnext:v15.78.1 networks: - frappe_network deploy: @@ -144,7 +144,7 @@ services: - logs:/home/frappe/frappe-bench/logs queue-short: - image: frappe/erpnext:v15.78.0 + image: frappe/erpnext:v15.78.1 networks: - frappe_network deploy: @@ -178,7 +178,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v15.78.0 + image: frappe/erpnext:v15.78.1 networks: - frappe_network deploy: @@ -192,7 +192,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v15.78.0 + image: frappe/erpnext:v15.78.1 networks: - frappe_network deploy: From 520b00ac1b5bd2d310e4c7c1244d58b62e09e700 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Sep 2025 07:29:03 +0530 Subject: [PATCH 010/279] chore(deps): bump actions/setup-go from 5 to 6 (#1691) Bumps [actions/setup-go](https://github.com/actions/setup-go) from 5 to 6. - [Release notes](https://github.com/actions/setup-go/releases) - [Commits](https://github.com/actions/setup-go/compare/v5...v6) --- updated-dependencies: - dependency-name: actions/setup-go dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/lint.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 4879c337..7e0b95c0 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -22,7 +22,7 @@ jobs: # For shfmt pre-commit hook - name: Setup Go - uses: actions/setup-go@v5 + uses: actions/setup-go@v6 with: go-version: "^1.14" From c2fb2055f04fa4d8ef010b1099a697d473f652bf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Sep 2025 07:29:33 +0530 Subject: [PATCH 011/279] chore(deps): bump actions/setup-python from 5 to 6 (#1692) Bumps [actions/setup-python](https://github.com/actions/setup-python) from 5 to 6. - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](https://github.com/actions/setup-python/compare/v5...v6) --- updated-dependencies: - dependency-name: actions/setup-python dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build_stable.yml | 2 +- .github/workflows/docker-build-push.yml | 2 +- .github/workflows/lint.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build_stable.yml b/.github/workflows/build_stable.yml index cd9e6139..6ddbb0ea 100644 --- a/.github/workflows/build_stable.yml +++ b/.github/workflows/build_stable.yml @@ -65,7 +65,7 @@ jobs: uses: actions/checkout@v5 - name: Setup Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: "3.10" diff --git a/.github/workflows/docker-build-push.yml b/.github/workflows/docker-build-push.yml index 2323cba7..d17dbf9e 100644 --- a/.github/workflows/docker-build-push.yml +++ b/.github/workflows/docker-build-push.yml @@ -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" diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 7e0b95c0..6f72e86b 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -16,7 +16,7 @@ jobs: uses: actions/checkout@v5 - name: Setup Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: "3.10.6" From 2f65520e14778df46f0c75fd6e1192c2106bb5e4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Sep 2025 07:30:06 +0530 Subject: [PATCH 012/279] chore(deps): bump actions/stale from 9 to 10 (#1693) Bumps [actions/stale](https://github.com/actions/stale) from 9 to 10. - [Release notes](https://github.com/actions/stale/releases) - [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/stale/compare/v9...v10) --- updated-dependencies: - dependency-name: actions/stale dependency-version: '10' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/stale.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 024ade1c..8849bfea 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -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. From 6e78467603a1d3cb44a2af34c4c794bf2966a68a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Sep 2025 07:30:37 +0530 Subject: [PATCH 013/279] chore(deps): bump pytest from 8.4.1 to 8.4.2 (#1694) Bumps [pytest](https://github.com/pytest-dev/pytest) from 8.4.1 to 8.4.2. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/8.4.1...8.4.2) --- updated-dependencies: - dependency-name: pytest dependency-version: 8.4.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements-test.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-test.txt b/requirements-test.txt index 8e0e8841..9471b3d9 100644 --- a/requirements-test.txt +++ b/requirements-test.txt @@ -1 +1 @@ -pytest==8.4.1 +pytest==8.4.2 From 2f5a42d864141216aa71dfa256e1ed18a0006c07 Mon Sep 17 00:00:00 2001 From: MeIchthys Date: Sat, 13 Sep 2025 02:54:41 -0400 Subject: [PATCH 014/279] Use `docker compose` instead of `docker-compose` (#1702) * Use `docker compose` instead of `docker-compose` Update to use new docker syntax. * use `docker` instead of `docker-compose` --- docs/site-operations.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/site-operations.md b/docs/site-operations.md index 550d9bdf..ef3b7b07 100644 --- a/docs/site-operations.md +++ b/docs/site-operations.md @@ -1,16 +1,16 @@ # Site operations -> πŸ’‘ You should setup `--project-name` option in `docker-compose` commands if you have non-standard project name. +> πŸ’‘ You should setup `--project-name` option in `docker` commands if you have non-standard project name. ## Setup new site Note: - Wait for the `db` service to start and `configurator` to exit before trying to create a new site. Usually this takes up to 10 seconds. -- Also you have to pass `-p ` if `-p` passed previously eg. `docker-compose -p exec (rest of the command)`. +- Also you have to pass `-p ` if `-p` passed previously eg. `docker -p exec (rest of the command)`. ```sh -docker-compose exec backend bench new-site --mariadb-user-host-login-scope=% --db-root-password --admin-password +docker exec backend bench new-site --mariadb-user-host-login-scope=% --db-root-password --admin-password ``` If you need to install some app, specify `--install-app`. To see all options, just run `bench new-site --help`. @@ -18,14 +18,14 @@ If you need to install some app, specify `--install-app`. To see all options, ju To create Postgres site (assuming you already use [Postgres compose override](images-and-compose-files.md#overrides)) you need have to do set `root_login` and `root_password` in common config before that: ```sh -docker-compose exec backend bench set-config -g root_login -docker-compose exec backend bench set-config -g root_password +docker exec backend bench set-config -g root_login +docker exec backend bench set-config -g root_password ``` Also command is slightly different: ```sh -docker-compose exec backend bench new-site --mariadb-user-host-login-scope=% --db-type postgres --admin-password +docker exec backend bench new-site --mariadb-user-host-login-scope=% --db-type postgres --admin-password ``` ## Push backup to S3 storage @@ -33,7 +33,7 @@ docker-compose exec backend bench new-site --mariadb-user-host-login-scope=% --d We have the script that helps to push latest backup to S3. ```sh -docker-compose exec backend push_backup.py --site-name --bucket --region-name --endpoint-url --aws-access-key-id --aws-secret-access-key +docker exec backend push_backup.py --site-name --bucket --region-name --endpoint-url --aws-access-key-id --aws-secret-access-key ``` Note that you can restore backup only manually. @@ -59,7 +59,7 @@ Instead of `alpine` use any image of your choice. For socketio and gunicorn service ping the hostname:port and that will be sufficient. For workers and scheduler, there is a command that needs to be executed. ```shell -docker-compose exec backend healthcheck.sh --ping-service mongodb:27017 +docker exec backend healthcheck.sh --ping-service mongodb:27017 ``` Additional services can be pinged as part of health check with option `-p` or `--ping-service`. @@ -72,7 +72,7 @@ If connection to service(s) fails, the command fails with exit code 1. For reference of commands like `backup`, `drop-site` or `migrate` check [official guide](https://frappeframework.com/docs/v13/user/en/bench/frappe-commands) or run: ```sh -docker-compose exec backend bench --help +docker exec backend bench --help ``` ## Migrate site @@ -82,5 +82,5 @@ Note: - Wait for the `db` service to start and `configurator` to exit before trying to migrate a site. Usually this takes up to 10 seconds. ```sh -docker-compose exec backend bench --site migrate +docker exec backend bench --site migrate ``` From b6e89163ecb6b15ff3057de52d82186c39442c30 Mon Sep 17 00:00:00 2001 From: MeIchthys Date: Mon, 15 Sep 2025 22:49:27 -0400 Subject: [PATCH 015/279] Revert "Use `docker compose` instead of `docker-compose` (#1702)" (#1708) This reverts commit 2f5a42d864141216aa71dfa256e1ed18a0006c07. --- docs/site-operations.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/site-operations.md b/docs/site-operations.md index ef3b7b07..550d9bdf 100644 --- a/docs/site-operations.md +++ b/docs/site-operations.md @@ -1,16 +1,16 @@ # Site operations -> πŸ’‘ You should setup `--project-name` option in `docker` commands if you have non-standard project name. +> πŸ’‘ You should setup `--project-name` option in `docker-compose` commands if you have non-standard project name. ## Setup new site Note: - Wait for the `db` service to start and `configurator` to exit before trying to create a new site. Usually this takes up to 10 seconds. -- Also you have to pass `-p ` if `-p` passed previously eg. `docker -p exec (rest of the command)`. +- Also you have to pass `-p ` if `-p` passed previously eg. `docker-compose -p exec (rest of the command)`. ```sh -docker exec backend bench new-site --mariadb-user-host-login-scope=% --db-root-password --admin-password +docker-compose exec backend bench new-site --mariadb-user-host-login-scope=% --db-root-password --admin-password ``` If you need to install some app, specify `--install-app`. To see all options, just run `bench new-site --help`. @@ -18,14 +18,14 @@ If you need to install some app, specify `--install-app`. To see all options, ju To create Postgres site (assuming you already use [Postgres compose override](images-and-compose-files.md#overrides)) you need have to do set `root_login` and `root_password` in common config before that: ```sh -docker exec backend bench set-config -g root_login -docker exec backend bench set-config -g root_password +docker-compose exec backend bench set-config -g root_login +docker-compose exec backend bench set-config -g root_password ``` Also command is slightly different: ```sh -docker exec backend bench new-site --mariadb-user-host-login-scope=% --db-type postgres --admin-password +docker-compose exec backend bench new-site --mariadb-user-host-login-scope=% --db-type postgres --admin-password ``` ## Push backup to S3 storage @@ -33,7 +33,7 @@ docker exec backend bench new-site --mariadb-user-host-login-scope=% --db-type p We have the script that helps to push latest backup to S3. ```sh -docker exec backend push_backup.py --site-name --bucket --region-name --endpoint-url --aws-access-key-id --aws-secret-access-key +docker-compose exec backend push_backup.py --site-name --bucket --region-name --endpoint-url --aws-access-key-id --aws-secret-access-key ``` Note that you can restore backup only manually. @@ -59,7 +59,7 @@ Instead of `alpine` use any image of your choice. For socketio and gunicorn service ping the hostname:port and that will be sufficient. For workers and scheduler, there is a command that needs to be executed. ```shell -docker exec backend healthcheck.sh --ping-service mongodb:27017 +docker-compose exec backend healthcheck.sh --ping-service mongodb:27017 ``` Additional services can be pinged as part of health check with option `-p` or `--ping-service`. @@ -72,7 +72,7 @@ If connection to service(s) fails, the command fails with exit code 1. For reference of commands like `backup`, `drop-site` or `migrate` check [official guide](https://frappeframework.com/docs/v13/user/en/bench/frappe-commands) or run: ```sh -docker exec backend bench --help +docker-compose exec backend bench --help ``` ## Migrate site @@ -82,5 +82,5 @@ Note: - Wait for the `db` service to start and `configurator` to exit before trying to migrate a site. Usually this takes up to 10 seconds. ```sh -docker exec backend bench --site migrate +docker-compose exec backend bench --site migrate ``` From f8f806b3a70b0ae3e89786a117c786f765920720 Mon Sep 17 00:00:00 2001 From: Marc Ramser Date: Tue, 16 Sep 2025 09:09:26 +0200 Subject: [PATCH 016/279] Upgrade node version (#1706) --- .github/workflows/build_develop.yml | 2 +- docker-bake.hcl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build_develop.yml b/.github/workflows/build_develop.yml index e37c5858..6103fd5f 100644 --- a/.github/workflows/build_develop.yml +++ b/.github/workflows/build_develop.yml @@ -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 }} diff --git a/docker-bake.hcl b/docker-bake.hcl index 3304ce40..9d3ccd00 100644 --- a/docker-bake.hcl +++ b/docker-bake.hcl @@ -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" { From 67500fa79af9c1222db3174f6ff3a506afc6f145 Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 16 Sep 2025 15:14:11 +0000 Subject: [PATCH 017/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 378a6324..3dfec476 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v15.78.1 +ERPNEXT_VERSION=v15.79.0 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index c75ec63e..da18563f 100644 --- a/pwd.yml +++ b/pwd.yml @@ -2,7 +2,7 @@ version: "3" services: backend: - image: frappe/erpnext:v15.78.1 + image: frappe/erpnext:v15.79.0 networks: - frappe_network deploy: @@ -18,7 +18,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v15.78.1 + image: frappe/erpnext:v15.79.0 networks: - frappe_network deploy: @@ -47,7 +47,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v15.78.1 + image: frappe/erpnext:v15.79.0 networks: - frappe_network deploy: @@ -102,7 +102,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v15.78.1 + image: frappe/erpnext:v15.79.0 networks: - frappe_network depends_on: @@ -128,7 +128,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v15.78.1 + image: frappe/erpnext:v15.79.0 networks: - frappe_network deploy: @@ -144,7 +144,7 @@ services: - logs:/home/frappe/frappe-bench/logs queue-short: - image: frappe/erpnext:v15.78.1 + image: frappe/erpnext:v15.79.0 networks: - frappe_network deploy: @@ -178,7 +178,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v15.78.1 + image: frappe/erpnext:v15.79.0 networks: - frappe_network deploy: @@ -192,7 +192,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v15.78.1 + image: frappe/erpnext:v15.79.0 networks: - frappe_network deploy: From 32f4fd315f4dce15aa0eb2555771780ba25fc476 Mon Sep 17 00:00:00 2001 From: Samar Singh <128586957+samarsingh6965@users.noreply.github.com> Date: Thu, 18 Sep 2025 04:43:41 +0530 Subject: [PATCH 018/279] =?UTF-8?q?Fix:=20Update=20PostgreSQL=2011.8=20?= =?UTF-8?q?=E2=86=92=2014=20for=20Frappe=20Site=20Creation=20(#1709)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * update version of postgress in compose.yml file * fix(postgres): upgrade to v14 for COMMIT AND CHAIN support --------- Co-authored-by: abhirock74 --- devcontainer-example/docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/devcontainer-example/docker-compose.yml b/devcontainer-example/docker-compose.yml index 3df5c417..39f509d5 100644 --- a/devcontainer-example/docker-compose.yml +++ b/devcontainer-example/docker-compose.yml @@ -15,7 +15,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: From c2679e20c3aef2d3cc39037801b297d7a8d09d14 Mon Sep 17 00:00:00 2001 From: github-actions Date: Sun, 21 Sep 2025 19:07:12 +0000 Subject: [PATCH 019/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 3dfec476..5e7d447f 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v15.79.0 +ERPNEXT_VERSION=v15.79.1 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index da18563f..b1a63d19 100644 --- a/pwd.yml +++ b/pwd.yml @@ -2,7 +2,7 @@ version: "3" services: backend: - image: frappe/erpnext:v15.79.0 + image: frappe/erpnext:v15.79.1 networks: - frappe_network deploy: @@ -18,7 +18,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v15.79.0 + image: frappe/erpnext:v15.79.1 networks: - frappe_network deploy: @@ -47,7 +47,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v15.79.0 + image: frappe/erpnext:v15.79.1 networks: - frappe_network deploy: @@ -102,7 +102,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v15.79.0 + image: frappe/erpnext:v15.79.1 networks: - frappe_network depends_on: @@ -128,7 +128,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v15.79.0 + image: frappe/erpnext:v15.79.1 networks: - frappe_network deploy: @@ -144,7 +144,7 @@ services: - logs:/home/frappe/frappe-bench/logs queue-short: - image: frappe/erpnext:v15.79.0 + image: frappe/erpnext:v15.79.1 networks: - frappe_network deploy: @@ -178,7 +178,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v15.79.0 + image: frappe/erpnext:v15.79.1 networks: - frappe_network deploy: @@ -192,7 +192,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v15.79.0 + image: frappe/erpnext:v15.79.1 networks: - frappe_network deploy: From 0c59c8475c7b678e3e753726a96b32c341de7cd0 Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 23 Sep 2025 07:48:35 +0000 Subject: [PATCH 020/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 5e7d447f..3fe006d3 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v15.79.1 +ERPNEXT_VERSION=v15.79.2 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index b1a63d19..5f7ea6c4 100644 --- a/pwd.yml +++ b/pwd.yml @@ -2,7 +2,7 @@ version: "3" services: backend: - image: frappe/erpnext:v15.79.1 + image: frappe/erpnext:v15.79.2 networks: - frappe_network deploy: @@ -18,7 +18,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v15.79.1 + image: frappe/erpnext:v15.79.2 networks: - frappe_network deploy: @@ -47,7 +47,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v15.79.1 + image: frappe/erpnext:v15.79.2 networks: - frappe_network deploy: @@ -102,7 +102,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v15.79.1 + image: frappe/erpnext:v15.79.2 networks: - frappe_network depends_on: @@ -128,7 +128,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v15.79.1 + image: frappe/erpnext:v15.79.2 networks: - frappe_network deploy: @@ -144,7 +144,7 @@ services: - logs:/home/frappe/frappe-bench/logs queue-short: - image: frappe/erpnext:v15.79.1 + image: frappe/erpnext:v15.79.2 networks: - frappe_network deploy: @@ -178,7 +178,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v15.79.1 + image: frappe/erpnext:v15.79.2 networks: - frappe_network deploy: @@ -192,7 +192,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v15.79.1 + image: frappe/erpnext:v15.79.2 networks: - frappe_network deploy: From 8b523ca12541ba003966a6f3e24a0edca1886c89 Mon Sep 17 00:00:00 2001 From: Niklas Liechti <2284764+nliechti@users.noreply.github.com> Date: Tue, 23 Sep 2025 10:00:48 +0200 Subject: [PATCH 021/279] Improve devcontainer behaviour on ARM Macs (#1707) * Remove hardcoded amd64 images. This slows down development on ARM Macs significantly. * Do not use prebuilt bench image as it may be outdated or not available as an ARM build. The source image is in this repo anyway. * Use the prebuilt image by default. --- devcontainer-example/docker-compose.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/devcontainer-example/docker-compose.yml b/devcontainer-example/docker-compose.yml index 39f509d5..0a614cbf 100644 --- a/devcontainer-example/docker-compose.yml +++ b/devcontainer-example/docker-compose.yml @@ -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 @@ -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 From 3b55b49cf8d9c7e85f694df2e98e608089ecf68c Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 23 Sep 2025 14:07:48 +0000 Subject: [PATCH 022/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 3fe006d3..103f761b 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v15.79.2 +ERPNEXT_VERSION=v15.80.0 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index 5f7ea6c4..bd0e52c2 100644 --- a/pwd.yml +++ b/pwd.yml @@ -2,7 +2,7 @@ version: "3" services: backend: - image: frappe/erpnext:v15.79.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.79.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.79.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.79.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.79.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.79.2 + image: frappe/erpnext:v15.80.0 networks: - frappe_network deploy: @@ -178,7 +178,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v15.79.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.79.2 + image: frappe/erpnext:v15.80.0 networks: - frappe_network deploy: From 1688a55d9322b8dd4b8372c147c49bd83862a3af Mon Sep 17 00:00:00 2001 From: github-actions Date: Thu, 25 Sep 2025 15:19:46 +0000 Subject: [PATCH 023/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 103f761b..0b885ac0 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v15.80.0 +ERPNEXT_VERSION=v15.80.1 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index bd0e52c2..4cc77380 100644 --- a/pwd.yml +++ b/pwd.yml @@ -2,7 +2,7 @@ version: "3" services: backend: - image: frappe/erpnext:v15.80.0 + image: frappe/erpnext:v15.80.1 networks: - frappe_network deploy: @@ -18,7 +18,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v15.80.0 + image: frappe/erpnext:v15.80.1 networks: - frappe_network deploy: @@ -47,7 +47,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v15.80.0 + image: frappe/erpnext:v15.80.1 networks: - frappe_network deploy: @@ -102,7 +102,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v15.80.0 + image: frappe/erpnext:v15.80.1 networks: - frappe_network depends_on: @@ -128,7 +128,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v15.80.0 + image: frappe/erpnext:v15.80.1 networks: - frappe_network deploy: @@ -144,7 +144,7 @@ services: - logs:/home/frappe/frappe-bench/logs queue-short: - image: frappe/erpnext:v15.80.0 + image: frappe/erpnext:v15.80.1 networks: - frappe_network deploy: @@ -178,7 +178,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v15.80.0 + image: frappe/erpnext:v15.80.1 networks: - frappe_network deploy: @@ -192,7 +192,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v15.80.0 + image: frappe/erpnext:v15.80.1 networks: - frappe_network deploy: From 72b8d262c9b6120dfb11ba3c3b927b4a03eb7e0e Mon Sep 17 00:00:00 2001 From: DanielRadlAMR Date: Mon, 29 Sep 2025 08:07:17 +0200 Subject: [PATCH 024/279] chore(deps): update MariaDB to v11.8 (LTS) (#1715) * chore(deps): update MariaDB to v11.8 (LTS) * fix(mariadb): replaced deprecated mysqladmin * feat(mariadb): make use of healthcheck.sh --- devcontainer-example/docker-compose.yml | 3 ++- overrides/compose.mariadb-secrets.yaml | 2 -- overrides/compose.mariadb-shared.yaml | 11 +++++++---- overrides/compose.mariadb.yaml | 11 +++++++---- 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/devcontainer-example/docker-compose.yml b/devcontainer-example/docker-compose.yml index 0a614cbf..0d6d9d8a 100644 --- a/devcontainer-example/docker-compose.yml +++ b/devcontainer-example/docker-compose.yml @@ -1,7 +1,7 @@ version: "3.7" services: mariadb: - image: docker.io/mariadb:10.6 + image: docker.io/mariadb:11.8 command: - --character-set-server=utf8mb4 - --collation-server=utf8mb4_unicode_ci @@ -9,6 +9,7 @@ services: - --skip-innodb-read-only-compressed # Temporary fix for MariaDB 10.6 environment: MYSQL_ROOT_PASSWORD: 123 + MARIADB_AUTO_UPGRADE: 1 volumes: - mariadb-data:/var/lib/mysql diff --git a/overrides/compose.mariadb-secrets.yaml b/overrides/compose.mariadb-secrets.yaml index a8172431..2e904463 100644 --- a/overrides/compose.mariadb-secrets.yaml +++ b/overrides/compose.mariadb-secrets.yaml @@ -3,8 +3,6 @@ services: 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 diff --git a/overrides/compose.mariadb-shared.yaml b/overrides/compose.mariadb-shared.yaml index 8872b48f..30d148e3 100644 --- a/overrides/compose.mariadb-shared.yaml +++ b/overrides/compose.mariadb-shared.yaml @@ -3,12 +3,14 @@ version: "3.3" services: database: container_name: mariadb-database - image: mariadb:10.6 + image: mariadb:11.8 restart: unless-stopped healthcheck: - test: mysqladmin ping -h localhost --password=${DB_PASSWORD:-changeit} - interval: 1s - retries: 20 + test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"] + start_period: 5s + interval: 5s + timeout: 5s + retries: 5 command: - --character-set-server=utf8mb4 - --collation-server=utf8mb4_unicode_ci @@ -16,6 +18,7 @@ services: - --skip-innodb-read-only-compressed environment: MYSQL_ROOT_PASSWORD: ${DB_PASSWORD:-changeit} + MARIADB_AUTO_UPGRADE: 1 volumes: - db-data:/var/lib/mysql networks: diff --git a/overrides/compose.mariadb.yaml b/overrides/compose.mariadb.yaml index ebce5038..22d95ea5 100644 --- a/overrides/compose.mariadb.yaml +++ b/overrides/compose.mariadb.yaml @@ -8,11 +8,13 @@ services: condition: service_healthy db: - image: mariadb:10.6 + image: mariadb:11.8 healthcheck: - test: mysqladmin ping -h localhost --password=${DB_PASSWORD:-123} - interval: 1s - retries: 20 + test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"] + start_period: 5s + interval: 5s + timeout: 5s + retries: 5 restart: unless-stopped command: - --character-set-server=utf8mb4 @@ -21,6 +23,7 @@ services: - --skip-innodb-read-only-compressed # Temporary fix for MariaDB 10.6 environment: MYSQL_ROOT_PASSWORD: ${DB_PASSWORD:-123} + MARIADB_AUTO_UPGRADE: 1 volumes: - db-data:/var/lib/mysql From 839fba504395e1ca4a585070cb5c8e1510c1d59c Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 30 Sep 2025 13:42:01 +0000 Subject: [PATCH 025/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 0b885ac0..63105422 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v15.80.1 +ERPNEXT_VERSION=v15.81.0 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index 4cc77380..69db51f6 100644 --- a/pwd.yml +++ b/pwd.yml @@ -2,7 +2,7 @@ version: "3" services: backend: - image: frappe/erpnext:v15.80.1 + image: frappe/erpnext:v15.81.0 networks: - frappe_network deploy: @@ -18,7 +18,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v15.80.1 + image: frappe/erpnext:v15.81.0 networks: - frappe_network deploy: @@ -47,7 +47,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v15.80.1 + image: frappe/erpnext:v15.81.0 networks: - frappe_network deploy: @@ -102,7 +102,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v15.80.1 + image: frappe/erpnext:v15.81.0 networks: - frappe_network depends_on: @@ -128,7 +128,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v15.80.1 + image: frappe/erpnext:v15.81.0 networks: - frappe_network deploy: @@ -144,7 +144,7 @@ services: - logs:/home/frappe/frappe-bench/logs queue-short: - image: frappe/erpnext:v15.80.1 + image: frappe/erpnext:v15.81.0 networks: - frappe_network deploy: @@ -178,7 +178,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v15.80.1 + image: frappe/erpnext:v15.81.0 networks: - frappe_network deploy: @@ -192,7 +192,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v15.80.1 + image: frappe/erpnext:v15.81.0 networks: - frappe_network deploy: From e6a1b778536e71d142a88f8f838ba02acfbf7fb7 Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 1 Oct 2025 15:28:21 +0000 Subject: [PATCH 026/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 63105422..470885a3 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v15.81.0 +ERPNEXT_VERSION=v15.81.1 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index 69db51f6..e5a482c6 100644 --- a/pwd.yml +++ b/pwd.yml @@ -2,7 +2,7 @@ version: "3" services: backend: - image: frappe/erpnext:v15.81.0 + image: frappe/erpnext:v15.81.1 networks: - frappe_network deploy: @@ -18,7 +18,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v15.81.0 + image: frappe/erpnext:v15.81.1 networks: - frappe_network deploy: @@ -47,7 +47,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v15.81.0 + image: frappe/erpnext:v15.81.1 networks: - frappe_network deploy: @@ -102,7 +102,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v15.81.0 + image: frappe/erpnext:v15.81.1 networks: - frappe_network depends_on: @@ -128,7 +128,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v15.81.0 + image: frappe/erpnext:v15.81.1 networks: - frappe_network deploy: @@ -144,7 +144,7 @@ services: - logs:/home/frappe/frappe-bench/logs queue-short: - image: frappe/erpnext:v15.81.0 + image: frappe/erpnext:v15.81.1 networks: - frappe_network deploy: @@ -178,7 +178,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v15.81.0 + image: frappe/erpnext:v15.81.1 networks: - frappe_network deploy: @@ -192,7 +192,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v15.81.0 + image: frappe/erpnext:v15.81.1 networks: - frappe_network deploy: From 9fec5ae4a5e300f8ca38a015bdb159a240e2e0ae Mon Sep 17 00:00:00 2001 From: github-actions Date: Mon, 6 Oct 2025 04:28:53 +0000 Subject: [PATCH 027/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 470885a3..0c5b3387 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v15.81.1 +ERPNEXT_VERSION=v15.81.2 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index e5a482c6..2eabd732 100644 --- a/pwd.yml +++ b/pwd.yml @@ -2,7 +2,7 @@ version: "3" services: backend: - image: frappe/erpnext:v15.81.1 + image: frappe/erpnext:v15.81.2 networks: - frappe_network deploy: @@ -18,7 +18,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v15.81.1 + image: frappe/erpnext:v15.81.2 networks: - frappe_network deploy: @@ -47,7 +47,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v15.81.1 + image: frappe/erpnext:v15.81.2 networks: - frappe_network deploy: @@ -102,7 +102,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v15.81.1 + image: frappe/erpnext:v15.81.2 networks: - frappe_network depends_on: @@ -128,7 +128,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v15.81.1 + image: frappe/erpnext:v15.81.2 networks: - frappe_network deploy: @@ -144,7 +144,7 @@ services: - logs:/home/frappe/frappe-bench/logs queue-short: - image: frappe/erpnext:v15.81.1 + image: frappe/erpnext:v15.81.2 networks: - frappe_network deploy: @@ -178,7 +178,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v15.81.1 + image: frappe/erpnext:v15.81.2 networks: - frappe_network deploy: @@ -192,7 +192,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v15.81.1 + image: frappe/erpnext:v15.81.2 networks: - frappe_network deploy: From f44a226c17535b2b3baa1924beb17a9fd39cc4b1 Mon Sep 17 00:00:00 2001 From: github-actions Date: Mon, 6 Oct 2025 15:18:47 +0000 Subject: [PATCH 028/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 0c5b3387..39017fa0 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v15.81.2 +ERPNEXT_VERSION=v15.81.3 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index 2eabd732..da7e2bf6 100644 --- a/pwd.yml +++ b/pwd.yml @@ -2,7 +2,7 @@ version: "3" services: backend: - image: frappe/erpnext:v15.81.2 + image: frappe/erpnext:v15.81.3 networks: - frappe_network deploy: @@ -18,7 +18,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v15.81.2 + image: frappe/erpnext:v15.81.3 networks: - frappe_network deploy: @@ -47,7 +47,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v15.81.2 + image: frappe/erpnext:v15.81.3 networks: - frappe_network deploy: @@ -102,7 +102,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v15.81.2 + image: frappe/erpnext:v15.81.3 networks: - frappe_network depends_on: @@ -128,7 +128,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v15.81.2 + image: frappe/erpnext:v15.81.3 networks: - frappe_network deploy: @@ -144,7 +144,7 @@ services: - logs:/home/frappe/frappe-bench/logs queue-short: - image: frappe/erpnext:v15.81.2 + image: frappe/erpnext:v15.81.3 networks: - frappe_network deploy: @@ -178,7 +178,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v15.81.2 + image: frappe/erpnext:v15.81.3 networks: - frappe_network deploy: @@ -192,7 +192,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v15.81.2 + image: frappe/erpnext:v15.81.3 networks: - frappe_network deploy: From 2aed90d861980e92a47fe3160a3f39bfecceb7b5 Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 7 Oct 2025 13:51:24 +0000 Subject: [PATCH 029/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 39017fa0..3f846e76 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v15.81.3 +ERPNEXT_VERSION=v15.82.0 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index da7e2bf6..2c81f72e 100644 --- a/pwd.yml +++ b/pwd.yml @@ -2,7 +2,7 @@ version: "3" services: backend: - image: frappe/erpnext:v15.81.3 + image: frappe/erpnext:v15.82.0 networks: - frappe_network deploy: @@ -18,7 +18,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v15.81.3 + image: frappe/erpnext:v15.82.0 networks: - frappe_network deploy: @@ -47,7 +47,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v15.81.3 + image: frappe/erpnext:v15.82.0 networks: - frappe_network deploy: @@ -102,7 +102,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v15.81.3 + image: frappe/erpnext:v15.82.0 networks: - frappe_network depends_on: @@ -128,7 +128,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v15.81.3 + image: frappe/erpnext:v15.82.0 networks: - frappe_network deploy: @@ -144,7 +144,7 @@ services: - logs:/home/frappe/frappe-bench/logs queue-short: - image: frappe/erpnext:v15.81.3 + image: frappe/erpnext:v15.82.0 networks: - frappe_network deploy: @@ -178,7 +178,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v15.81.3 + image: frappe/erpnext:v15.82.0 networks: - frappe_network deploy: @@ -192,7 +192,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v15.81.3 + image: frappe/erpnext:v15.82.0 networks: - frappe_network deploy: From c6511f14534d9aec1d59f2241efd5470b0a8a092 Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 8 Oct 2025 15:05:10 +0000 Subject: [PATCH 030/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 3f846e76..bfdbf606 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v15.82.0 +ERPNEXT_VERSION=v15.82.1 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index 2c81f72e..51a8c713 100644 --- a/pwd.yml +++ b/pwd.yml @@ -2,7 +2,7 @@ version: "3" services: backend: - image: frappe/erpnext:v15.82.0 + image: frappe/erpnext:v15.82.1 networks: - frappe_network deploy: @@ -18,7 +18,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v15.82.0 + image: frappe/erpnext:v15.82.1 networks: - frappe_network deploy: @@ -47,7 +47,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v15.82.0 + image: frappe/erpnext:v15.82.1 networks: - frappe_network deploy: @@ -102,7 +102,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v15.82.0 + image: frappe/erpnext:v15.82.1 networks: - frappe_network depends_on: @@ -128,7 +128,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v15.82.0 + image: frappe/erpnext:v15.82.1 networks: - frappe_network deploy: @@ -144,7 +144,7 @@ services: - logs:/home/frappe/frappe-bench/logs queue-short: - image: frappe/erpnext:v15.82.0 + image: frappe/erpnext:v15.82.1 networks: - frappe_network deploy: @@ -178,7 +178,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v15.82.0 + image: frappe/erpnext:v15.82.1 networks: - frappe_network deploy: @@ -192,7 +192,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v15.82.0 + image: frappe/erpnext:v15.82.1 networks: - frappe_network deploy: From 5b8cbd3aeee637cda3cb539c0ebd1d8895738923 Mon Sep 17 00:00:00 2001 From: jobafr <81627156+jobafr@users.noreply.github.com> Date: Tue, 14 Oct 2025 13:58:18 +0200 Subject: [PATCH 031/279] add correct redis URLs to environment of other containers (#1718) --- pwd.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pwd.yml b/pwd.yml index 51a8c713..01be6e8b 100644 --- a/pwd.yml +++ b/pwd.yml @@ -142,6 +142,9 @@ services: volumes: - sites:/home/frappe/frappe-bench/sites - logs:/home/frappe/frappe-bench/logs + environment: + FRAPPE_REDIS_CACHE: redis://redis-cache:6379 + FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: image: frappe/erpnext:v15.82.1 @@ -158,6 +161,9 @@ services: volumes: - sites:/home/frappe/frappe-bench/sites - logs:/home/frappe/frappe-bench/logs + environment: + FRAPPE_REDIS_CACHE: redis://redis-cache:6379 + FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 redis-queue: image: redis:6.2-alpine @@ -201,6 +207,9 @@ services: command: - node - /home/frappe/frappe-bench/apps/frappe/socketio.js + environment: + FRAPPE_REDIS_CACHE: redis://redis-cache:6379 + FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 volumes: - sites:/home/frappe/frappe-bench/sites - logs:/home/frappe/frappe-bench/logs From ffd2aa47a6d6985befc15588dfdbcafb15a3d9bd Mon Sep 17 00:00:00 2001 From: DanielRadlAMR Date: Tue, 14 Oct 2025 14:01:25 +0200 Subject: [PATCH 032/279] docs: reorganize container setup information into new subfolder docs/container-setup (#1720) --- README.md | 7 +- docs/container-setup/01-overview.md | 47 ++++++++ docs/container-setup/02-build-setup.md | 121 +++++++++++++++++++ docs/container-setup/03-start-setup.md | 42 +++++++ docs/container-setup/env-variables.md | 112 ++++++++++++++++++ docs/container-setup/overrider.md | 27 +++++ docs/custom-apps-podman.md | 125 -------------------- docs/custom-apps.md | 156 ------------------------- docs/environment-variables.md | 60 ---------- docs/list-of-containers.md | 58 --------- 10 files changed, 352 insertions(+), 403 deletions(-) create mode 100644 docs/container-setup/01-overview.md create mode 100644 docs/container-setup/02-build-setup.md create mode 100644 docs/container-setup/03-start-setup.md create mode 100644 docs/container-setup/env-variables.md create mode 100644 docs/container-setup/overrider.md delete mode 100644 docs/custom-apps-podman.md delete mode 100644 docs/custom-apps.md delete mode 100644 docs/environment-variables.md delete mode 100644 docs/list-of-containers.md diff --git a/README.md b/README.md index 32edc8e4..da11161a 100644 --- a/README.md +++ b/README.md @@ -53,9 +53,9 @@ If you ran in a Dev Docker environment, to view container logs: `docker compose ### [Production](#production) -- [List of containers](docs/list-of-containers.md) +- [List of containers](docs/container-setup/01-overview.md) - [Single Compose Setup](docs/single-compose-setup.md) -- [Environment Variables](docs/environment-variables.md) +- [Environment Variables](docs/container-setup/env-variables.md) - [Single Server Example](docs/single-server-example.md) - [Setup Options](docs/setup-options.md) - [Site Operations](docs/site-operations.md) @@ -67,8 +67,7 @@ If you ran in a Dev Docker environment, to view container logs: `docker compose ### [Custom Images](#custom-images) -- [Custom Apps](docs/custom-apps.md) -- [Custom Apps with podman](docs/custom-apps-podman.md) +- [Custom Apps](docs/container-setup/02-build-setup.md) - [Build Version 10 Images](docs/build-version-10-images.md) ### [Development](#development) diff --git a/docs/container-setup/01-overview.md b/docs/container-setup/01-overview.md new file mode 100644 index 00000000..ee266886 --- /dev/null +++ b/docs/container-setup/01-overview.md @@ -0,0 +1,47 @@ +The purpose of this document is to give you an overview of how the Frappe Docker containers are structured. + +# 🐳 Images + +There are **four predefined Dockerfiles** available in the `/images` directory. + +| Dockerfile | Ingredients | Purpose & Use Case | +| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **bench** | Sets up only the Bench CLI. | Used for **development** or debugging. Provides the command-line tooling but does not include runtime services. | +| **custom** | Multi-purpose Python backend built from a plain Python image. Includes everything needed to run a Frappe instance via a Compose setup. Installs apps defined in `apps.json`. | Suitable for **production** and **testing**. Ideal when you need control over dependencies (e.g. trying new Python or Node versions). | +| **layered** | Final contents are the same as `custom`, but it is based on **prebuilt images from [Docker Hub](https://hub.docker.com/u/frappe)**. | Great for **production builds** when you’re fine with the dependency versions managed by Frappe. Builds much faster since the base layers are already prepared. | +| **production** | Similar to `custom` (built from a Python base image), but installs **only Frappe and ERPNext**. Not customizable with `apps.json`. | Best for **quick starts** or exploration. For real deployments or CI/CD pipelines, `custom` or `layered` are preferred because they offer more flexibility. | + +--- + +These images include everything needed to run all processes required by the Frappe framework +(see [Bench Procfile reference](https://frappeframework.com/docs/v14/user/en/bench/resources/bench-procfile)). + +- The `bench` image only sets up the CLI tool. +- The other images (`custom`, `layered`, and `production`) go further β€” enabling a nearly **plug-and-play** setup for ERPNext and custom apps. + +> We use [multi-stage builds](https://docs.docker.com/develop/develop-images/multistage-build/) and [Docker Buildx](https://docs.docker.com/engine/reference/commandline/buildx/) to maximize layer reuse and make our builds more efficient. + +# πŸ—οΈ Compose + +Once images are built, containers are orchestrated using a [compose file](https://docs.docker.com/compose/compose-file/). The main compose.yaml provides core services, networking, and volumes for any Frappe setup. + +## πŸ› οΈ Services + +| Service | Role | Purpose | +| ---------------- | --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **configurator** | Setup | Updates `common_site_config.json` so Frappe knows how to access db and redis. It is executed on every `docker-compose up` (and exited immediately). Other services start after this container exits successfully | +| **backend** | Runtime | [Werkzeug server](https://werkzeug.palletsprojects.com/en/2.0.x/) | +| **frontend** | Proxy | [nginx](https://www.nginx.com) server that serves JS/CSS assets and routes incoming requests | +| **websocket** | Real-time | Node server that runs [Socket.IO](https://socket.io) | +| **queue-\_** | Background Jobs | Python servers that run job queues using [rq](https://python-rq.org) | +| **scheduler** | Task Automation | Python server that runs tasks on schedule using [schedule](https://schedule.readthedocs.io/en/stable/) | + +## 🧩 Overrides + +Additional functionality can be added using [overrides](https://docs.docker.com/compose/extends/). These files modify existing services or add new ones without changing the main `compose.yaml`. + +Example: The main compose file has no database service, but `compose.mariadb.yaml` adds MariaDB. See [overrider.md](overrider.md) for the complete list of available overrides and how to use them. + +--- + +**Next:** [Build Setup β†’](02-build-setup.md) diff --git a/docs/container-setup/02-build-setup.md b/docs/container-setup/02-build-setup.md new file mode 100644 index 00000000..55034165 --- /dev/null +++ b/docs/container-setup/02-build-setup.md @@ -0,0 +1,121 @@ +This guide walks you through building Frappe images from the repository resources. + +# Prerequisites + +- git +- docker or podman +- docker compose v2 or podman compose + +> Install containerization software according to the official maintainer documentation. Avoid package managers when not recommended, as they frequently cause compatibility issues. + +# Clone this repo + +```bash +git clone https://github.com/frappe/frappe_docker +cd frappe_docker +``` + +# Define custom apps + +If you dont want to install specific apps to the image skip this section. + +To include custom apps in your image, create an `apps.json` file in the repository root: + +```json +[ + { + "url": "https://github.com/frappe/erpnext", + "branch": "version-15" + }, + { + "url": "https://github.com/frappe/hrms", + "branch": "version-15" + }, + { + "url": "https://github.com/frappe/helpdesk", + "branch": "main" + } +] +``` + +Then generate a base64-encoded string from this file: + +```bash +export APPS_JSON_BASE64=$(base64 -w 0 apps.json) +``` + +# Build the image + +Choose the appropriate build command based on your container runtime and desired image type. This example builds the `layered` image with the custom `apps.json` you created. + +`Docker`: + +```bash +docker build \ + --build-arg=FRAPPE_PATH=https://github.com/frappe/frappe \ + --build-arg=FRAPPE_BRANCH=version-15 \ + --build-arg=APPS_JSON_BASE64=$APPS_JSON_BASE64 \ + --tag=custom:15 \ + --file=images/layered/Containerfile . +``` + +`Podman`: + +```bash +podman build \ + --build-arg=FRAPPE_PATH=https://github.com/frappe/frappe \ + --build-arg=FRAPPE_BRANCH=version-15 \ + --build-arg=APPS_JSON_BASE64=$APPS_JSON_BASE64 \ + --tag=custom:15 \ + --file=images/layered/Containerfile . +``` + +## Build args + +| Arg | Purpose | +| -------------------- | --------------------------------------------------------------------------------------------- | +| **Frappe Framework** | | +| FRAPPE_PATH | Repository URL for Frappe framework source code. Defaults to https://github.com/frappe/frappe | +| FRAPPE_BRANCH | Branch to use for Frappe framework. Defaults to version-15 | +| **Custom Apps** | | +| APPS_JSON_BASE64 | Base64-encoded JSON string from apps.json defining apps to install | +| **Dependencies** | | +| PYTHON_VERSION | Python version for the base image | +| NODE_VERSION | Node.js version | +| WKHTMLTOPDF_VERSION | wkhtmltopdf version | +| **bench only** | | +| DEBIAN_BASE | Debian base version for the bench image, defaults to `bookworm` | +| WKHTMLTOPDF_DISTRO | use the specified distro for debian package. Default is `bookworm` | + +# env file + +The compose file requires several environment variables. You can either export them on your system or create a `.env` file. + +```bash +cp example.env custom.env +``` + +Edit `custom.env` to customize variables for your setup. The template includes common variables, but you can add, modify, or remove any as needed. See [env-variables.md](env-variables.md) for detailed descriptions of all available variables. + +# Creating the final compose file + +Combine the base compose file with appropriate overrides for your use case. This example adds MariaDB, Redis, and exposes ports on `:8080`: + +```bash +docker compose --env.file example.env \ + -f compose.yaml \ + -f overrides/compose.mariadb.yaml \ + -f overrides/compose.redis.yaml \ + -f overrides/compose.noproxy.yaml \ + config > compose.custom.yaml +``` + +This generates `compose.custom.yaml`, which you'll use to start all containers. Customize the overrides and environment variables according to your requirements. + +> **NOTE**: podman compose is just a wrapper, it uses docker-compose if it is available or podman-compose if not. podman-compose have an issue reading .env files ([Issue](https://github.com/containers/podman-compose/issues/475)) and might create an issue when running the containers. + +--- + +**Next:** [Start Setup β†’](03-start-setup.md) + +**Back:** [Container Overview ←](01-overview.md) diff --git a/docs/container-setup/03-start-setup.md b/docs/container-setup/03-start-setup.md new file mode 100644 index 00000000..e19df758 --- /dev/null +++ b/docs/container-setup/03-start-setup.md @@ -0,0 +1,42 @@ +# start Container + +Once your compose file is ready, start all containers with a single command: + +```bash +docker compose -p frappe -f compose.custom.yaml up -d +``` + +```bash +podman-compose --in-pod=1 --project-name frappe -f compose.custom.yaml up -d +``` + +The `-p` (or `--project-name`) flag names the project `frappe`, allowing you to easily reference and manage all containers together. + +# Create a site and install apps + +Frappe is now running, but it's not yet configured. You need to create a site and install your apps. + +```bash +docker compose -p frappe exec backend bench new-site --mariadb-user-host-login-scope='172.%.%.%' +docker compose -p frappe exec backend bench --site install-app erpnext +``` + +```bash +podman exec -ti erpnext_backend_1 /bin/bash +bench new-site --mariadb-user-host-login-scope='172.%.%.%' +bench --site install-app erpnext +``` + +Replace `` with your desired site name. + +> ## Understanding the MariaDB User Scope +> +> The flag --mariadb-user-host-login-scope='172.%.%.%' allows database connections from any IP address within the 172.0.0.0/8 range. This includes all containers and virtual machines running on your machine. +> +> **Why is this necessary?** Docker and Podman assign dynamic IP addresses to containers. If you set a fixed IP address instead, database connections will fail when the container restarts and receives a new IP. The wildcard pattern ensures connections always work, regardless of IP changes. +> +> **Security note:** This scope is sufficient because only the backend container accesses the database. If you need external database access, adjust the scope accordingly, but be cautious with overly permissive settings. + +--- + +**Back:** [Build Setup β†’](02-build-setup.md) diff --git a/docs/container-setup/env-variables.md b/docs/container-setup/env-variables.md new file mode 100644 index 00000000..1001c888 --- /dev/null +++ b/docs/container-setup/env-variables.md @@ -0,0 +1,112 @@ +# Environment Variables Reference + +Environment variables configure your Frappe Docker setup. They can be set directly in the container or defined in a `.env` file referenced by Docker Compose. + +**Getting Started:** + +```bash +cp example.env .env +``` + +Then edit `.env` and set variables according to your needs. + +--- + +## Required Variables + +| Variable | Purpose | Example | Notes | +| ----------------- | ------------------------------------------------ | -------------------------------- | ---------------------------------------------------------------- | +| `FRAPPE_PATH` | Frappe framework path | https://github.com/frappe/frappe | | +| `FRAPPE_BRANCH` | Frappe Branch | `version-15` | See [Frappe releases](https://github.com/frappe/frappe/releases) | +| `ERPNEXT_VERSION` | ERPNext release version | `v15.67.0` | Required although its never used | +| `DB_PASSWORD` | Password for database root (MariaDB or Postgres) | `secure_password_123` | Not needed if using `DB_PASSWORD_SECRETS_FILE` | + +--- + +## Database Configuration + +| Variable | Purpose | Default | When to Set | +| -------------------------- | ----------------------------------------- | ------------------------------------ | ---------------------------------- | +| `DB_PASSWORD` | Database root user password | 123 | Always (unless using secrets file) | +| `DB_PASSWORD_SECRETS_FILE` | Path to file containing database password | β€” | Setup mariadb-secrets overrider | +| `DB_HOST` | Database hostname or IP | `db` (service name) | Only if using external database | +| `DB_PORT` | Database port | `3306` (MariaDB) / `5432` (Postgres) | Only if using external database | + +--- + +## Redis Configuration + +| Variable | Purpose | Default | When to Set | +| ------------- | --------------------------------------------------- | ---------------------------- | ------------------------------------- | +| `REDIS_CACHE` | Redis hostname for caching | `redis-cache` (service name) | Only if using external Redis instance | +| `REDIS_QUEUE` | Redis hostname for job queues and real-time updates | `redis-queue` (service name) | Only if using external Redis instance | + +--- + +## HTTPS & SSL Configuration + +| Variable | Purpose | Default | When to Set | +| ------------------- | ------------------------------------------------ | ------- | ---------------------------------------- | +| `LETSENCRYPT_EMAIL` | Email for Let's Encrypt certificate registration | β€” | Required if using HTTPS override | +| `SITES` | List of domains for SSL certificates | β€” | Required if using reverse proxy override | + +**Format for `SITES`:** + +```bash +# Single site +SITES=`mysite.example.com` + +# Wildcard (any subdomain) +SITES=`{any:.+}` +``` + +--- + +## Site Configuration + +| Variable | Purpose | Default | When to Set | +| ------------------------- | -------------------------------- | ---------------------------------------- | ----------------------------------------------- | +| `FRAPPE_SITE_NAME_HEADER` | Site name for multi-tenant setup | `$host` (resolved from request hostname) | When accessing by IP or need explicit site name | + +**Examples:** + +If your site is named `mysite` but you want to access it via `127.0.0.1`: + +```bash +FRAPPE_SITE_NAME_HEADER=mysite +``` + +If your site is named `example.com` and you access it via that domain, no need to set this (defaults to hostname). + +--- + +## Image Configuration + +| Variable | Purpose | Default | Notes | +| ---------------- | ------------------------------ | --------------------- | ------------------------------------------------------- | +| `CUSTOM_IMAGE` | Custom Docker image repository | Frappe official image | Leave empty to use default | +| `CUSTOM_TAG` | Custom Docker image tag | Latest stable | Corresponds to `FRAPPE_VERSION` | +| `PULL_POLICY` | Image pull behavior | `always` | Options: `always`, `never`, `if-not-present` | +| `RESTART_POLICY` | Container restart behavior | `unless-stopped` | Options: `no`, `always`, `unless-stopped`, `on-failure` | + +--- + +## Nginx Proxy Configuration + +| Variable | Purpose | Default | Allowed Values | +| ---------------------- | ---------------------------------- | -------------- | -------------------------------------------- | +| `BACKEND` | Backend service address and port | `0.0.0.0:8000` | `{host}:{port}` | +| `SOCKETIO` | Socket.IO service address and port | `0.0.0.0:9000` | `{host}:{port}` | +| `HTTP_PUBLISH_PORT` | Published HTTP port | `8080` | Any available port | +| `PROXY_READ_TIMEOUT` | Upstream request timeout | `120s` | Any nginx timeout value (e.g., `300s`, `5m`) | +| `CLIENT_MAX_BODY_SIZE` | Maximum upload file size | `50m` | Any nginx size value (e.g., `100m`, `1g`) | + +### Real IP Configuration (Behind Proxy) + +Use these variables when running behind a reverse proxy or load balancer: + +| Variable | Purpose | Default | +| ---------------------------- | ------------------------------------------------- | ----------------- | +| `UPSTREAM_REAL_IP_ADDRESS` | Trusted upstream IP address for real IP detection | `127.0.0.1` | +| `UPSTREAM_REAL_IP_HEADER` | Request header containing client IP | `X-Forwarded-For` | +| `UPSTREAM_REAL_IP_RECURSIVE` | Enable recursive IP search | `off` | diff --git a/docs/container-setup/overrider.md b/docs/container-setup/overrider.md new file mode 100644 index 00000000..9188489d --- /dev/null +++ b/docs/container-setup/overrider.md @@ -0,0 +1,27 @@ +Overrides extend the base compose.yaml with additional services or modify existing behavior. Include them in your compose command using multiple -f flags. + +```bash +docker compose -f compose.yaml -f overrides/compose.mariadb.yaml -f overrides/compose.redis.yaml config > compose.custom.yaml +``` + +| Overrider | Purpose | Additional Info | +| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | +| **Database** | | | +| compose.mariadb.yaml | Adds MariaDB database service | set `DB_PASSWORD` or default Password will be used | +| compose.mariadb-secrets.yaml | Adds MariaDB with password from a secret file instead of environment variable | Set `DB_PASSWORD_SECRETS_FILE` to the path of your secret file | +| compose.mariadb-shared.yaml | Makes MariaDB available on a shared network (mariadb-network) for other services | set `DB_PASSWORD` | +| compose.postgres.yaml | Uses PostgreSQL instead of MariaDB as the database | set `DB_PASSWORD` | +| **Proxy** | | | +| compose.noproxy.yaml | Exposes the application directly on port `:8080` without a reverse proxy | | +| compose.proxy.yaml | Uses Traefik as HTTP reverse proxy on port `:80` | You can change the published port by setting `HTTP_PUBLISH_PORT` | +| compose.https.yaml | Uses Traefik as HTTPS reverse proxy on Port `:443` with automatic HTTP-to-HTTPS redirect | `SITES` and `LETSENCRYPT_EMAIL` must be set. `HTTP_PUBLISH_PORT` and `HTTPS_PUBLISH_PORT` can be set. | +| **Redis** | | | +| compose.redis.yaml | Adds Redis service for caching and background job queuing | +| **TBD** | **The following overrides are available but lack documentation. If you use them and understand their purpose, please consider contributing to this documentation.** | +| compose.backup-cron.yaml | | | +| compose.custom-domain-ssl.yaml | | | +| compose.custom-domain.yaml | | | +| compose.multi-bench-ssl.yaml | | | +| compose.multi-bench.yaml | | | +| compose.traefik-ssl.yaml | | | +| compose.traefik.yaml | | | diff --git a/docs/custom-apps-podman.md b/docs/custom-apps-podman.md deleted file mode 100644 index 765b9b7d..00000000 --- a/docs/custom-apps-podman.md +++ /dev/null @@ -1,125 +0,0 @@ -## Prerequisites - -- podman -- podman-compose -- docker-compose - -Podman (the POD MANager) is a tool for managing containers and images, volumes mounted into those containers, and pods made from groups of containers. It is available on the official repositories of many Linux distributions. - -## Step 1 - -- Clone this repository and change the current directory to the downloaded folder - ```cmd - git clone https://github.com/frappe/frappe_docker - cd frappe_docker - ``` - -## Step 2 - -- Create `apps.json` file with custom apps listed in it - ```json - [ - { - "url": "https://github.com/frappe/erpnext", - "branch": "version-15" - }, - { - "url": "https://github.com/frappe/hrms", - "branch": "version-15" - }, - { - "url": "https://github.com/frappe/helpdesk", - "branch": "main" - } - ] - ``` - Check the syntax of the file using `jq empty apps.json` - ### Generate base64 string from JSON file: - `cmd export APPS_JSON_BASE64=$(base64 -w 0 apps.json)` - -## Step 3 - -- Building the custom image using podman - -```ruby - podman build \ - --build-arg=FRAPPE_PATH=https://github.com/frappe/frappe \ - --build-arg=FRAPPE_BRANCH=version-15 \ - --build-arg=APPS_JSON_BASE64=$APPS_JSON_BASE64 \ - --tag=custom:15 \ - --file=images/layered/Containerfile . -``` - -### Note - -- Make sure to use the same tag when you export a variable on the next step - -## Step 4 - -- Using the image -- Export environment variables with image name, tag and pull_policy - ```ruby - export CUSTOM_IMAGE=custom - export CUSTOM_TAG=15 - export PULL_POLICY=never - ``` -- Configuration of parameters used when starting the containers - - create `.env` file copying from example.env (Read more on setting up environment variables [here](https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md) - -## Final step - -- Creating a compose file -- ```ruby - podman compose -f compose.yaml \ - -f overrides/compose.mariadb.yaml \ - -f overrides/compose.redis.yaml \ - -f overrides/compose.noproxy.yaml \ - config > ./docker-compose.yml - ``` - ### NOTE - - podman compose is just a wrapper, it uses docker-compose if it is available or podman-compose if not. podman-compose have an issue reading .env files ([Issue](https://github.com/containers/podman-compose/issues/475)) and might create an issue when running the containers. -- Creating pod and starting the containers - - `podman-compose --in-pod=1 --project-name erpnext -f ./docker-compose.yml up -d` - -## Creating sites and installing apps - -- You can create sites from the backend container - - `podman exec -ti erpnext_backend_1 /bin/bash` - - `bench new-site myerp.net --mariadb-root-password 123456 --admin-password 123123` - - `bench --site myerp.net install-app erpnext` - -## Autostart pod - -- Systemd is the best option on autostart pods when the system boots. Create a unit file in either `/etc/systemd/system` [for root user] or `~/.config/systemd/user` [for non-root user] - - ```ruby - [Unit] - Description=Podman system daemon service - After=network-online.target - - [Service] - #User= - #Group= - Type=oneshot - ExecStart=podman pod start POD_NAME - - - [Install] - WantedBy=default.target - - ``` - - **Note:** Replace POD_NAME with a created pod name while creating a pod. This is a basic systemd unit file to autostart pod, but multiple options can be used, refer to the man page for [systemd](https://man7.org/linux/man-pages/man1/init.1.html). For better management of containers, [Quadlet](https://docs.podman.io/en/v4.4/markdown/podman-systemd.unit.5.html) is the best option for ease of updating and tracing issues on each container. - -## Troubleshoot - -- If there is a network issue while building the image, you need to remove caches and restart again - - - `podman system reset` - - `sudo rm -rf ~/.local/share/containers/ /var/lib/container ~/.caches/containers` - -- Database issue when restarting the container - - Execute the following commands from **backend** container - - `mysql -uroot -padmin -hdb` (Note: put your db password in place of _admin_). - - `SELECT User, Host FROM mysql.user;` - - Change the IP address to %, e.g. `RENAME USER '_5e5899d8398b5f7b'@'172.18.0.7' TO '_5e5899d8398b5f7b'@'%'` diff --git a/docs/custom-apps.md b/docs/custom-apps.md deleted file mode 100644 index 544bdee4..00000000 --- a/docs/custom-apps.md +++ /dev/null @@ -1,156 +0,0 @@ -### Load custom apps through apps.json file - -Base64 encoded string of `apps.json` file needs to be passed in as build arg environment variable. - -Create the following `apps.json` file: - -```json -[ - { - "url": "https://github.com/frappe/erpnext", - "branch": "version-15" - }, - { - "url": "https://github.com/frappe/payments", - "branch": "version-15" - }, - { - "url": "https://{{ PAT }}@git.example.com/project/repository.git", - "branch": "main" - } -] -``` - -Note: - -- The `url` needs to be http(s) git url with personal access tokens without username eg:- `http://{{PAT}}@github.com/project/repository.git` in case of private repo. -- Add dependencies manually in `apps.json` e.g. add `erpnext` if you are installing `hrms`. -- Use fork repo or branch for ERPNext in case you need to use your fork or test a PR. - -Generate base64 string from json file: - -```shell -export APPS_JSON_BASE64=$(base64 -w 0 /path/to/apps.json) -``` - -Test the Previous Step: Decode the Base64-encoded Environment Variable - -To verify the previous step, decode the `APPS_JSON_BASE64` environment variable (which is Base64-encoded) into a JSON file. Follow the steps below: - -1. Use the following command to decode and save the output into a JSON file named apps-test-output.json: - -```shell -echo -n ${APPS_JSON_BASE64} | base64 -d > apps-test-output.json -``` - -2. Open the apps-test-output.json file to review the JSON output and ensure that the content is correct. - -### Clone frappe_docker and switch directory - -```shell -git clone https://github.com/frappe/frappe_docker -cd frappe_docker -``` - -### Configure build - -Common build args. - -- `FRAPPE_PATH`, customize the source repo for frappe framework. Defaults to `https://github.com/frappe/frappe` -- `FRAPPE_BRANCH`, customize the source repo branch for frappe framework. Defaults to `version-15`. -- `APPS_JSON_BASE64`, correct base64 encoded JSON string generated from `apps.json` file. - -Notes - -- Use `buildah` or `docker` as per your setup. -- Make sure `APPS_JSON_BASE64` variable has correct base64 encoded JSON string. It is consumed as build arg, base64 encoding ensures it to be friendly with environment variables. Use `jq empty apps.json` to validate `apps.json` file. -- Make sure the `--tag` is valid image name that will be pushed to registry. See section [below](#use-images) for remarks about its use. -- `.git` directories for all apps are removed from the image. - -### Quick build image - -This method uses pre-built `frappe/base:${FRAPPE_BRANCH}` and `frappe/build:${FRAPPE_BRANCH}` image layers which come with required Python and NodeJS runtime. It speeds up the build time. - -It uses `images/layered/Containerfile`. - -```shell -docker build \ - --build-arg=FRAPPE_PATH=https://github.com/frappe/frappe \ - --build-arg=FRAPPE_BRANCH=version-15 \ - --build-arg=APPS_JSON_BASE64=$APPS_JSON_BASE64 \ - --tag=ghcr.io/user/repo/custom:1.0.0 \ - --file=images/layered/Containerfile . -``` - -### Custom build image - -This method builds the base and build layer every time, it allows to customize Python and NodeJS runtime versions. It takes more time to build. - -It uses `images/custom/Containerfile`. - -```shell -docker build \ - --build-arg=FRAPPE_PATH=https://github.com/frappe/frappe \ - --build-arg=FRAPPE_BRANCH=version-15 \ - --build-arg=PYTHON_VERSION=3.11.9 \ - --build-arg=NODE_VERSION=20.19.2 \ - --build-arg=APPS_JSON_BASE64=$APPS_JSON_BASE64 \ - --tag=ghcr.io/user/repo/custom:1.0.0 \ - --file=images/custom/Containerfile . -``` - -Custom build args, - -- `PYTHON_VERSION`, use the specified python version for base image. Default is `3.11.6`. -- `NODE_VERSION`, use the specified nodejs version, Default `20.19.2`. -- `DEBIAN_BASE` use the base Debian version, defaults to `bookworm`. -- `WKHTMLTOPDF_VERSION`, use the specified qt patched `wkhtmltopdf` version. Default is `0.12.6.1-3`. -- `WKHTMLTOPDF_DISTRO`, use the specified distro for debian package. Default is `bookworm`. - -### Push image to use in yaml files - -Login to `docker` or `buildah` - -```shell -docker login -``` - -Push image - -```shell -docker push ghcr.io/user/repo/custom:1.0.0 -``` - -### Use Images - -In the [compose.yaml](../compose.yaml), you can set the image name and tag through environment variables, making it easier to customize. - -```yaml -x-customizable-image: &customizable_image - image: ${CUSTOM_IMAGE:-frappe/erpnext}:${CUSTOM_TAG:-${ERPNEXT_VERSION:?No ERPNext version or tag set}} - pull_policy: ${PULL_POLICY:-always} -``` - -The environment variables can be set in the shell or in the .env file as [setup-options.md](setup-options.md) describes. - -- `CUSTOM_IMAGE`: The name of your custom image. Defaults to `frappe/erpnext` if not set. -- `CUSTOM_TAG`: The tag for your custom image. Must be set if `CUSTOM_IMAGE` is used. Defaults to the value of `ERPNEXT_VERSION` if not set. -- `PULL_POLICY`: The Docker pull policy. Defaults to `always`. Recommended set to `never` for local images, so prevent `docker` from trying to download the image when it has been built locally. -- `HTTP_PUBLISH_PORT`: The port to publish through no SSL channel. Default depending on deployment, it may be `80` if SSL activated or `8080` if not. -- `HTTPS_PUBLISH_PORT`: The secure port to publish using SSL. Default is `443`. - -Make sure the image name is correct before pushing to the registry. After the images are pushed, you can pull them to servers to be deployed. If the registry is private, additional auth is needed. - -#### Example - -If you built an image with the tag `ghcr.io/user/repo/custom:1.0.0`, you would set the environment variables as follows: - -```bash -export CUSTOM_IMAGE='ghcr.io/user/repo/custom' -export CUSTOM_TAG='1.0.0' -docker compose -f compose.yaml \ - -f overrides/compose.mariadb.yaml \ - -f overrides/compose.redis.yaml \ - -f overrides/compose.https.yaml \ - config > ~/gitops/docker-compose.yaml -``` diff --git a/docs/environment-variables.md b/docs/environment-variables.md deleted file mode 100644 index 616b06fa..00000000 --- a/docs/environment-variables.md +++ /dev/null @@ -1,60 +0,0 @@ -## Environment Variables - -All of the commands are directly passed to container as per type of service. Only environment variables used in image are for `nginx-entrypoint.sh` command. They are as follows: - -- `BACKEND`: Set to `{host}:{port}`, defaults to `0.0.0.0:8000` -- `SOCKETIO`: Set to `{host}:{port}`, defaults to `0.0.0.0:9000` -- `UPSTREAM_REAL_IP_ADDRESS`: Set Nginx config for [ngx_http_realip_module#set_real_ip_from](http://nginx.org/en/docs/http/ngx_http_realip_module.html#set_real_ip_from), defaults to `127.0.0.1` -- `UPSTREAM_REAL_IP_HEADER`: Set Nginx config for [ngx_http_realip_module#real_ip_header](http://nginx.org/en/docs/http/ngx_http_realip_module.html#real_ip_header), defaults to `X-Forwarded-For` -- `UPSTREAM_REAL_IP_RECURSIVE`: Set Nginx config for [ngx_http_realip_module#real_ip_recursive](http://nginx.org/en/docs/http/ngx_http_realip_module.html#real_ip_recursive) Set defaults to `off` -- `FRAPPE_SITE_NAME_HEADER`: Set proxy header `X-Frappe-Site-Name` and serve site named in the header, defaults to `$host`, i.e. find site name from host header. More details [below](#frappe_site_name_header) -- `PROXY_READ_TIMEOUT`: Upstream gunicorn service timeout, defaults to `120` -- `CLIENT_MAX_BODY_SIZE`: Max body size for uploads, defaults to `50m` - -To bypass `nginx-entrypoint.sh`, mount desired `/etc/nginx/conf.d/default.conf` and run `nginx -g 'daemon off;'` as container command. - -## Configuration - -We use environment variables to configure our setup. docker-compose uses variables from the `environment:` section of the services defined within and the`.env` file, if present. Variables defined in the `.env` file are referenced via `${VARIABLE_NAME}` within the docker-compose `.yml` file. `example.env` contains a non-exhaustive list of possible configuration variables. To get started, copy `example.env` to `.env`. - -### `FRAPPE_VERSION` - -Frappe framework release. You can find all releases [here](https://github.com/frappe/frappe/releases). - -### `DB_PASSWORD` - -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. - -### `DB_PORT` - -Port for MariaDB (3306) or Postgres (5432) database. Set only if external service for database is used. - -### `REDIS_CACHE` - -Hostname for redis server to store cache. Set only if external service for redis is used or the container can not be reached by its service name (redis-cache) by other containers. - -### `REDIS_QUEUE` - -Hostname for redis server to store queue data and socketio. Set only if external service for redis is used or the container can not be reached by its service name (redis-queue) by other containers. - -### `ERPNEXT_VERSION` - -ERPNext [release](https://github.com/frappe/erpnext/releases). This variable is required if you use ERPNext override. - -### `LETSENCRYPT_EMAIL` - -Email that used to register https certificate. This one is required only if you use HTTPS override. - -### `FRAPPE_SITE_NAME_HEADER` - -This environment variable is not required. Default value is `$$host` which resolves site by host. For example, if your host is `example.com`, site's name should be `example.com`, or if host is `127.0.0.1` (local debugging), it should be `127.0.0.1` This variable allows to override described behavior. Let's say you create site named `mysite` and do want to access it by `127.0.0.1` host. Than you would set this variable to `mysite`. - -There is other variables not mentioned here. They're somewhat internal and you don't have to worry about them except you want to change main compose file. diff --git a/docs/list-of-containers.md b/docs/list-of-containers.md deleted file mode 100644 index 5ed757d5..00000000 --- a/docs/list-of-containers.md +++ /dev/null @@ -1,58 +0,0 @@ -# Images - -There are 3 images that you can find in `/images` directory: - -- `bench`. It is used for development. [Learn more how to start development](development.md). -- `production`. - - Multi-purpose Python backend. Runs [Werkzeug server](https://werkzeug.palletsprojects.com/en/2.0.x/) with [gunicorn](https://gunicorn.org), queues (via `bench worker`), or schedule (via `bench schedule`). - - Contains JS and CSS assets and routes incoming requests using [nginx](https://www.nginx.com). - - Processes realtime websocket requests using [Socket.IO](https://socket.io). -- `custom`. It is used to build bench using `apps.json` file set with `--apps_path` during bench initialization. `apps.json` is a json array. e.g. `[{"url":"{{repo_url}}","branch":"{{repo_branch}}"}]` - -Image has everything we need to be able to run all processes that Frappe framework requires (take a look at [Bench Procfile reference](https://frappeframework.com/docs/v14/user/en/bench/resources/bench-procfile)). We follow [Docker best practices](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#decouple-applications) and split these processes to different containers. - -> We use [multi-stage builds](https://docs.docker.com/develop/develop-images/multistage-build/) and [Docker Buildx](https://docs.docker.com/engine/reference/commandline/buildx/) to reuse as much things as possible and make our builds more efficient. - -# Compose files - -After building the images we have to run the containers. The best and simplest way to do this is to use [compose files](https://docs.docker.com/compose/compose-file/). - -We have one main compose file, `compose.yaml`. Services described, networking, volumes are also handled there. - -## Services - -All services are described in `compose.yaml` - -- `configurator`. Updates `common_site_config.json` so Frappe knows how to access db and redis. It is executed on every `docker-compose up` (and exited immediately). Other services start after this container exits successfully. -- `backend`. [Werkzeug server](https://werkzeug.palletsprojects.com/en/2.0.x/). -- `db`. Optional service that runs [MariaDB](https://mariadb.com) if you also use `overrides/compose.mariadb.yaml` or [Postgres](https://www.postgresql.org) if you also use `overrides/compose.postgres.yaml`. -- `redis`. Optional service that runs [Redis](https://redis.io) server with cache, [Socket.IO](https://socket.io) and queues data. -- `frontend`. [nginx](https://www.nginx.com) server that serves JS/CSS assets and routes incoming requests. -- `proxy`. [Traefik](https://traefik.io/traefik/) proxy. It is here for complicated setups or HTTPS override (with `overrides/compose.https.yaml`). -- `websocket`. Node server that runs [Socket.IO](https://socket.io). -- `queue-short`, `queue-long`. Python servers that run job queues using [rq](https://python-rq.org). -- `scheduler`. Python server that runs tasks on schedule using [schedule](https://schedule.readthedocs.io/en/stable/). - -## Overrides - -We have several [overrides](https://docs.docker.com/compose/extends/): - -- `overrides/compose.proxy.yaml`. Adds traefik proxy to setup. -- `overrides/compose.noproxy.yaml`. Publishes `frontend` ports directly without any proxy. -- `overrides/compose.https.yaml`. Automatically sets up Let's Encrypt certificate and redirects all requests to directed to http, to https. -- `overrides/compose.mariadb.yaml`. Adds `db` service and sets its image to MariaDB. -- `overrides/compose.postgres.yaml`. Adds `db` service and sets its image to Postgres. Note that ERPNext currently doesn't support Postgres. -- `overrides/compose.redis.yaml`. Adds `redis` service and sets its image to `redis`. - -It is quite simple to run overrides. All we need to do is to specify compose files that should be used by docker-compose. For example, we want ERPNext: - -```bash -# Point to main compose file (compose.yaml) and add one more. -docker-compose -f compose.yaml -f overrides/compose.redis.yaml config -``` - -⚠ Make sure to use docker-compose v2 (run `docker-compose -v` to check). If you want to use v1 make sure the correct `$`-signs as they get duplicated by the `config` command! - -That's it! Of course, we also have to setup `.env` before all of that, but that's not the point. - -Check [environment variables](environment-variables.md) for more. From 828a7db8330155798fc16bb4306e6283da0018c4 Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 14 Oct 2025 14:36:46 +0000 Subject: [PATCH 033/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index bfdbf606..11b3d090 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v15.82.1 +ERPNEXT_VERSION=v15.83.0 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index 01be6e8b..971865fc 100644 --- a/pwd.yml +++ b/pwd.yml @@ -2,7 +2,7 @@ version: "3" services: backend: - image: frappe/erpnext:v15.82.1 + image: frappe/erpnext:v15.83.0 networks: - frappe_network deploy: @@ -18,7 +18,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v15.82.1 + image: frappe/erpnext:v15.83.0 networks: - frappe_network deploy: @@ -47,7 +47,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v15.82.1 + image: frappe/erpnext:v15.83.0 networks: - frappe_network deploy: @@ -102,7 +102,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v15.82.1 + image: frappe/erpnext:v15.83.0 networks: - frappe_network depends_on: @@ -128,7 +128,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v15.82.1 + image: frappe/erpnext:v15.83.0 networks: - frappe_network deploy: @@ -147,7 +147,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v15.82.1 + image: frappe/erpnext:v15.83.0 networks: - frappe_network deploy: @@ -184,7 +184,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v15.82.1 + image: frappe/erpnext:v15.83.0 networks: - frappe_network deploy: @@ -198,7 +198,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v15.82.1 + image: frappe/erpnext:v15.83.0 networks: - frappe_network deploy: From 5fb1f96b3cb00e88480857e0aea419fd7060d5bb Mon Sep 17 00:00:00 2001 From: github-actions Date: Fri, 17 Oct 2025 09:52:22 +0000 Subject: [PATCH 034/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 11b3d090..6deda245 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v15.83.0 +ERPNEXT_VERSION=v15.83.1 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index 971865fc..afae04f4 100644 --- a/pwd.yml +++ b/pwd.yml @@ -2,7 +2,7 @@ version: "3" services: backend: - image: frappe/erpnext:v15.83.0 + image: frappe/erpnext:v15.83.1 networks: - frappe_network deploy: @@ -18,7 +18,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v15.83.0 + image: frappe/erpnext:v15.83.1 networks: - frappe_network deploy: @@ -47,7 +47,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v15.83.0 + image: frappe/erpnext:v15.83.1 networks: - frappe_network deploy: @@ -102,7 +102,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v15.83.0 + image: frappe/erpnext:v15.83.1 networks: - frappe_network depends_on: @@ -128,7 +128,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v15.83.0 + image: frappe/erpnext:v15.83.1 networks: - frappe_network deploy: @@ -147,7 +147,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v15.83.0 + image: frappe/erpnext:v15.83.1 networks: - frappe_network deploy: @@ -184,7 +184,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v15.83.0 + image: frappe/erpnext:v15.83.1 networks: - frappe_network deploy: @@ -198,7 +198,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v15.83.0 + image: frappe/erpnext:v15.83.1 networks: - frappe_network deploy: From f9b0943923065aed34b596345f81284be3bad25b Mon Sep 17 00:00:00 2001 From: github-actions Date: Sat, 18 Oct 2025 05:15:04 +0000 Subject: [PATCH 035/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 6deda245..27335625 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v15.83.1 +ERPNEXT_VERSION=v15.83.2 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index afae04f4..ce51a924 100644 --- a/pwd.yml +++ b/pwd.yml @@ -2,7 +2,7 @@ version: "3" services: backend: - image: frappe/erpnext:v15.83.1 + image: frappe/erpnext:v15.83.2 networks: - frappe_network deploy: @@ -18,7 +18,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v15.83.1 + image: frappe/erpnext:v15.83.2 networks: - frappe_network deploy: @@ -47,7 +47,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v15.83.1 + image: frappe/erpnext:v15.83.2 networks: - frappe_network deploy: @@ -102,7 +102,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v15.83.1 + image: frappe/erpnext:v15.83.2 networks: - frappe_network depends_on: @@ -128,7 +128,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v15.83.1 + image: frappe/erpnext:v15.83.2 networks: - frappe_network deploy: @@ -147,7 +147,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v15.83.1 + image: frappe/erpnext:v15.83.2 networks: - frappe_network deploy: @@ -184,7 +184,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v15.83.1 + image: frappe/erpnext:v15.83.2 networks: - frappe_network deploy: @@ -198,7 +198,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v15.83.1 + image: frappe/erpnext:v15.83.2 networks: - frappe_network deploy: From a5d472ba89b46f455013dbdacc1d941687bcf3f1 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Tue, 21 Oct 2025 12:47:23 +0530 Subject: [PATCH 036/279] Fix MIME type detection by adding media-types package to Docker images (#1725) * Initial plan * Add media-types package to fix MIME type detection in Docker images Co-authored-by: ankush <9079960+ankush@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: ankush <9079960+ankush@users.noreply.github.com> --- images/bench/Dockerfile | 2 ++ images/custom/Containerfile | 2 ++ images/production/Containerfile | 2 ++ 3 files changed, 6 insertions(+) diff --git a/images/bench/Dockerfile b/images/bench/Dockerfile index 1b8a92de..181a6623 100644 --- a/images/bench/Dockerfile +++ b/images/bench/Dockerfile @@ -71,6 +71,8 @@ RUN apt-get update \ tk-dev \ liblzma-dev \ file \ + # For MIME type detection + media-types \ && rm -rf /var/lib/apt/lists/* RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen \ diff --git a/images/custom/Containerfile b/images/custom/Containerfile index 208f13e3..06182d42 100644 --- a/images/custom/Containerfile +++ b/images/custom/Containerfile @@ -37,6 +37,8 @@ RUN useradd -ms /bin/bash frappe \ # For healthcheck wait-for-it \ jq \ + # For MIME type detection + media-types \ # NodeJS && mkdir -p ${NVM_DIR} \ && curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.5/install.sh | bash \ diff --git a/images/production/Containerfile b/images/production/Containerfile index 050fec4b..563bc763 100644 --- a/images/production/Containerfile +++ b/images/production/Containerfile @@ -34,6 +34,8 @@ RUN useradd -ms /bin/bash frappe \ # For healthcheck wait-for-it \ jq \ + # For MIME type detection + media-types \ # NodeJS && mkdir -p ${NVM_DIR} \ && curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.5/install.sh | bash \ From a830f288d8d3f1028162a11a653b1b068fe2d07f Mon Sep 17 00:00:00 2001 From: Fitzroy Zeng <90667163+FitzroyZ@users.noreply.github.com> Date: Tue, 21 Oct 2025 15:22:06 +0800 Subject: [PATCH 037/279] Fix typo in Docker compose command (#1724) --- docs/container-setup/02-build-setup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/container-setup/02-build-setup.md b/docs/container-setup/02-build-setup.md index 55034165..0e3f0e36 100644 --- a/docs/container-setup/02-build-setup.md +++ b/docs/container-setup/02-build-setup.md @@ -102,7 +102,7 @@ Edit `custom.env` to customize variables for your setup. The template includes c Combine the base compose file with appropriate overrides for your use case. This example adds MariaDB, Redis, and exposes ports on `:8080`: ```bash -docker compose --env.file example.env \ +docker compose --env-file example.env \ -f compose.yaml \ -f overrides/compose.mariadb.yaml \ -f overrides/compose.redis.yaml \ From ea00b0ec9d1fbdda95fefbb4704d01c0240a0eef Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 21 Oct 2025 13:17:36 +0000 Subject: [PATCH 038/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 27335625..1747505c 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v15.83.2 +ERPNEXT_VERSION=v15.84.0 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index ce51a924..100a71bc 100644 --- a/pwd.yml +++ b/pwd.yml @@ -2,7 +2,7 @@ version: "3" services: backend: - image: frappe/erpnext:v15.83.2 + image: frappe/erpnext:v15.84.0 networks: - frappe_network deploy: @@ -18,7 +18,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v15.83.2 + image: frappe/erpnext:v15.84.0 networks: - frappe_network deploy: @@ -47,7 +47,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v15.83.2 + image: frappe/erpnext:v15.84.0 networks: - frappe_network deploy: @@ -102,7 +102,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v15.83.2 + image: frappe/erpnext:v15.84.0 networks: - frappe_network depends_on: @@ -128,7 +128,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v15.83.2 + image: frappe/erpnext:v15.84.0 networks: - frappe_network deploy: @@ -147,7 +147,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v15.83.2 + image: frappe/erpnext:v15.84.0 networks: - frappe_network deploy: @@ -184,7 +184,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v15.83.2 + image: frappe/erpnext:v15.84.0 networks: - frappe_network deploy: @@ -198,7 +198,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v15.83.2 + image: frappe/erpnext:v15.84.0 networks: - frappe_network deploy: From f73b7909a07d84d476ec8729446aa860de65a3f6 Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 28 Oct 2025 14:24:14 +0000 Subject: [PATCH 039/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 1747505c..8683d454 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v15.84.0 +ERPNEXT_VERSION=v15.85.0 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index 100a71bc..b89ffe17 100644 --- a/pwd.yml +++ b/pwd.yml @@ -2,7 +2,7 @@ version: "3" services: backend: - image: frappe/erpnext:v15.84.0 + image: frappe/erpnext:v15.85.0 networks: - frappe_network deploy: @@ -18,7 +18,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v15.84.0 + image: frappe/erpnext:v15.85.0 networks: - frappe_network deploy: @@ -47,7 +47,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v15.84.0 + image: frappe/erpnext:v15.85.0 networks: - frappe_network deploy: @@ -102,7 +102,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v15.84.0 + image: frappe/erpnext:v15.85.0 networks: - frappe_network depends_on: @@ -128,7 +128,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v15.84.0 + image: frappe/erpnext:v15.85.0 networks: - frappe_network deploy: @@ -147,7 +147,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v15.84.0 + image: frappe/erpnext:v15.85.0 networks: - frappe_network deploy: @@ -184,7 +184,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v15.84.0 + image: frappe/erpnext:v15.85.0 networks: - frappe_network deploy: @@ -198,7 +198,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v15.84.0 + image: frappe/erpnext:v15.85.0 networks: - frappe_network deploy: From 78d21c2f4e79ac3974f4f4484290b8da4ba1adc0 Mon Sep 17 00:00:00 2001 From: github-actions Date: Thu, 30 Oct 2025 16:17:49 +0000 Subject: [PATCH 040/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 8683d454..8a2c509c 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v15.85.0 +ERPNEXT_VERSION=v15.85.1 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index b89ffe17..97cc8844 100644 --- a/pwd.yml +++ b/pwd.yml @@ -2,7 +2,7 @@ version: "3" services: backend: - image: frappe/erpnext:v15.85.0 + image: frappe/erpnext:v15.85.1 networks: - frappe_network deploy: @@ -18,7 +18,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v15.85.0 + image: frappe/erpnext:v15.85.1 networks: - frappe_network deploy: @@ -47,7 +47,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v15.85.0 + image: frappe/erpnext:v15.85.1 networks: - frappe_network deploy: @@ -102,7 +102,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v15.85.0 + image: frappe/erpnext:v15.85.1 networks: - frappe_network depends_on: @@ -128,7 +128,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v15.85.0 + image: frappe/erpnext:v15.85.1 networks: - frappe_network deploy: @@ -147,7 +147,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v15.85.0 + image: frappe/erpnext:v15.85.1 networks: - frappe_network deploy: @@ -184,7 +184,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v15.85.0 + image: frappe/erpnext:v15.85.1 networks: - frappe_network deploy: @@ -198,7 +198,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v15.85.0 + image: frappe/erpnext:v15.85.1 networks: - frappe_network deploy: From a7ccf3565d00089241857fd9671c222ad0660b7e Mon Sep 17 00:00:00 2001 From: duthink Date: Fri, 31 Oct 2025 19:20:01 +0530 Subject: [PATCH 041/279] docs: Add comprehensive Getting Started guide for Frappe Docker --- README.md | 4 + docs/getting-started.md | 953 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 957 insertions(+) create mode 100644 docs/getting-started.md diff --git a/README.md b/README.md index da11161a..6a208926 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,8 @@ Everything about [Frappe](https://github.com/frappe/frappe) and [ERPNext](https: # Getting Started +**New to Frappe Docker?** Read the [Getting Started Guide](docs/getting-started.md) for a comprehensive overview of repository structure, development workflow, custom apps, Docker concepts, and quick start examples. + To get started you need [Docker](https://docs.docker.com/get-docker/), [docker-compose](https://docs.docker.com/compose/), and [git](https://docs.github.com/en/get-started/getting-started-with-git/set-up-git) setup on your machine. For Docker basics and best practices refer to Docker's [documentation](http://docs.docker.com). Once completed, chose one of the following two sections for next steps. @@ -49,6 +51,8 @@ If you ran in a Dev Docker environment, to view container logs: `docker compose # Documentation +### [Getting Started Guide](docs/getting-started.md) + ### [Frequently Asked Questions](https://github.com/frappe/frappe_docker/wiki/Frequently-Asked-Questions) ### [Production](#production) diff --git a/docs/getting-started.md b/docs/getting-started.md new file mode 100644 index 00000000..fa7b6c62 --- /dev/null +++ b/docs/getting-started.md @@ -0,0 +1,953 @@ +# Getting Started with Frappe Docker + +_A comprehensive guide for developers getting started with Frappe Docker, with comparisons to Django for teams familiar with that framework_ + +## Table of Contents + +- [How to Use This Guide](#how-to-use-this-guide) +- [Understanding Frappe Docker Architecture](#understanding-frappe-docker-architecture) +- [Repository Structure](#repository-structure) +- [Custom Apps Explained](#custom-apps-explained) +- [Development Workflow](#development-workflow) +- [Platform Notes](#platform-notes) +- [File Locations and Access](#file-locations-and-access) +- [Docker Concepts: Bind Mounts](#docker-concepts-bind-mounts) +- [Fork Management Best Practices](#fork-management-best-practices) +- [Quick Start Examples](#quick-start-examples) +- [Framework Comparisons](#framework-comparisons) + - [Frappe vs Django](#frappe-vs-django-concepts) +- [Resources and References](#resources-and-references) + +--- + +## How to Use This Guide + +Walk through the sections sequentially if you're onboarding from scratch, or jump directly using the Table of Contents. + +## 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. + +### 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 +- **scheduler** - Cron-style task scheduler for periodic jobs +- **websocket** - Socket.IO server for real-time communications +- **db** - MariaDB/PostgreSQL database server +- **redis-cache/queue** - Redis for caching and job queue management + +### How Services Work Together + +``` +User Request + ↓ +[frontend (Nginx)] β†’ Static files served directly + ↓ +[backend (Gunicorn)] β†’ 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 + +### πŸ“ 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 + +- **images/bench/** - Development container with full Frappe tooling and CLI +- **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: + +- **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 +- **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) + +### πŸ“ resources/ - Runtime Templates + +- **nginx-entrypoint.sh** - Dynamic Nginx configuration generator script +- **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 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 +``` + +## 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 +docker compose -f pwd.yml up -d + +# Monitor site creation (takes ~5 minutes) +docker compose -f pwd.yml logs -f create-site + +# Access once "create-site" container exits successfully +# Visit http://localhost:8080 +# Login: Administrator / admin +``` + +### 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 + # Follow interactive prompts for site name, apps to install, etc. + ``` + +4. **Access development files:** + ``` + development/frappe-bench/ # Your live development environment + ``` + +### Development File Locations + +``` +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 +``` + +### Common Development Commands + +```bash +# Inside container +bench start # Start development server with hot-reload + +# Database operations +bench migrate # Run database migrations +bench --site mysite.com migrate # Site-specific migration + +# Frontend builds +bench build # Build all app assets +bench build --app my_custom_app # Build specific app + +# Code generation +bench new-app # Create new app +bench new-site # Create new site + +# App management +bench get-app # Download app from git +bench install-app # Install app to current site +bench uninstall-app # Remove app from site + +# Debugging +bench console # Python REPL with Frappe context +bench mariadb # Database console +``` + +## Platform Notes + +### 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. + +## File Locations and Access + +### Accessing Container Files + +```bash +# Enter backend container shell +docker compose -f pwd.yml exec backend bash + +# Navigate to bench directory +cd /home/frappe/frappe-bench/ + +# Key directories: +/home/frappe/frappe-bench/apps/ # All Frappe apps +/home/frappe/frappe-bench/sites/ # Site data and configuration +/home/frappe/frappe-bench/logs/ # Application logs +/home/frappe/frappe-bench/env/ # Python virtual environment +``` + +### 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/ + +# Copy 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/ +``` + +### Useful Container Commands + +```bash +# List all sites +docker compose -f pwd.yml exec backend bench list-sites + +# List installed apps for a site +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 + +# Check logs in real-time +docker compose -f pwd.yml logs -f backend + +# Execute bench command +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 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 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. + +## 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/production/ # Production containers +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" +``` + +## Quick Start Examples + +### 1. Quick Test (5 minutes) + +**Goal:** Try Frappe/ERPNext without any local setup + +```bash +# Clone and run +git clone https://github.com/frappe/frappe_docker +cd frappe_docker +docker compose -f pwd.yml up -d + +# Monitor setup progress (~5 minutes) +docker compose -f pwd.yml logs -f create-site + +# When complete, access: +# URL: http://localhost:8080 +# Username: Administrator +# Password: admin + +# Cleanup when done +docker compose -f pwd.yml down -v +``` + +### 2. Development Environment (15 minutes) + +**Goal:** Set up for daily development with hot-reload + +```bash +# Copy devcontainer config +cp -R devcontainer-example .devcontainer + +# Open in VSCode +# 1. Install "Dev Containers" extension +# 2. Command Palette (Ctrl+Shift+P) β†’ "Reopen in Container" +# 3. Wait for container build (~5 min first time) + +# Inside container terminal: +cd /workspace/development +python installer.py + +# Follow prompts: +# - Site name: development.localhost +# - Install ERPNext: Yes +# - Version: version-15 + +# Start development server +cd frappe-bench +bench start + +# Access: http://localhost:8000 +# Edit files in: development/frappe-bench/apps/ +``` + +### 3. Custom App Development (30 minutes) + +**Goal:** Create and develop a custom Frappe application + +```bash +# Prerequisite: Complete Example 2 first + +# Inside development container +cd /workspace/development/frappe-bench + +# Create new app +bench new-app library_management +# Follow prompts (title, description, publisher, etc.) + +# Install to site +bench --site development.localhost install-app library_management + +# Create DocTypes via web UI: +# 1. Go to: http://localhost:8000 +# 2. Setup β†’ Customize β†’ DocType β†’ New +# 3. Create: Book, Author, Borrower, etc. + +# Or create via code: +# Edit: apps/library_management/library_management/library_management/doctype/ + +# Build and reload +bench build --app library_management +# Server auto-reloads (bench start watches for changes) +``` + +### 4. Production Deployment (1 hour) + +**Goal:** Deploy Frappe in production with SSL + +```bash +# Follow detailed guide +# See: docs/single-server-example.md + +# Quick overview: +# 1. Setup server with Docker +# 2. Clone frappe_docker +# 3. Configure environment variables +# 4. Use compose.yaml + production overrides +# 5. Setup SSL with Traefik/Let's Encrypt +# 6. Deploy and monitor + +# Key files: +# - compose.yaml +# - compose.mariadb.yaml +# - compose.redis.yaml +# - compose.proxy.yaml +# - compose.https.yaml + +# Deploy command: +docker compose \ + -f compose.yaml \ + -f overrides/compose.mariadb.yaml \ + -f overrides/compose.redis.yaml \ + -f overrides/compose.https.yaml \ + up -d +``` + +### 5. Multi-Site Hosting + +**Goal:** Host multiple Frappe sites on one server + +```bash +# See: docs/port-based-multi-tenancy.md + +# Quick example: +# 1. Create multiple sites in development +bench new-site site1.com +bench new-site site2.com + +# 2. Configure Nginx/Traefik for routing +# 3. Each site gets own database +# 4. Shared Redis and application code +``` + +--- + +## 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. + +--- + +## 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 +- [Docker Documentation](https://docs.docker.com) - Docker fundamentals + +### Key Files in This Repository + +- [`docs/development.md`](development.md) - Detailed development setup +- [`docs/container-setup/env-variables.md`](container-setup/env-variables.md) - Environment variable reference +- [`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 +- [`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 +docker compose down # Stop and remove containers +docker compose down -v # Stop and remove volumes (data loss!) +docker compose restart # Restart specific service +docker compose ps # List running services +docker compose logs -f # Follow logs for service + +# Container Access +docker compose exec bash # Open shell in running container +docker compose exec # Run command in container +docker compose run # Run one-off command (creates new container) + +# Debugging +docker compose logs --tail=100 # Last 100 log lines +docker compose top # Show running processes +docker inspect # Detailed container info + +# Cleanup +docker system prune # Remove unused containers/networks +docker volume prune # Remove unused volumes (BE CAREFUL!) +docker image prune # Remove unused images +``` + +### Essential Bench Commands Reference + +```bash +# Site Operations +bench new-site # Create new site +bench drop-site # Delete site (asks confirmation) +bench list-sites # List all sites +bench use # Set default site + +# App Operations +bench get-app # Download app from git +bench get-app # Download from Frappe registry +bench install-app # Install to default site +bench install-app --site # Install to specific site +bench uninstall-app # Uninstall from default site +bench list-apps # List installed apps + +# Development +bench start # Start development server (hot-reload) +bench build # Build frontend assets +bench build --app # Build specific app +bench migrate # Run database migrations +bench clear-cache # Clear Redis cache +bench clear-website-cache # Clear website route cache + +# Database +bench mariadb # Open MariaDB console +bench backup # Backup default site +bench backup --with-files # Backup with uploaded files +bench restore # Restore backup + +# Code Generation +bench new-app # Create new app +bench --site console # Python REPL with Frappe context +bench --site execute "" # Execute Python code + +# Deployment +bench setup production # Setup for production (supervisor, nginx) +bench restart # Restart bench processes +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 ` | +| 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 ` 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) +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) + +### Contributing + +Found issues or improvements for this guide? + +- Create an issue: [frappe_docker/issues](https://github.com/frappe/frappe_docker/issues) +- Submit focused PRs: keep updates scoped and split large efforts across multiple pull requests. +- Review [CONTRIBUTING.md](../CONTRIBUTING.md) for coding standards and review expectations. + +--- + +_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_ From 41f30248c9795498e15bbd35d2a3a37e7bdc594e Mon Sep 17 00:00:00 2001 From: duthink Date: Tue, 4 Nov 2025 12:40:15 +0530 Subject: [PATCH 042/279] docs: Revise core services section in Getting Started guide for clarity and accuracy --- docs/getting-started.md | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/docs/getting-started.md b/docs/getting-started.md index fa7b6c62..ea615c37 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -30,13 +30,19 @@ Frappe Docker provides a comprehensive containerized environment for developing ### 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 -- **scheduler** - Cron-style task scheduler for periodic jobs -- **websocket** - Socket.IO server for real-time communications -- **db** - MariaDB/PostgreSQL database server -- **redis-cache/queue** - Redis for caching and job queue management +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 @@ -45,7 +51,7 @@ User Request ↓ [frontend (Nginx)] β†’ Static files served directly ↓ -[backend (Gunicorn)] β†’ Dynamic content processing +[backend (Werkzeug)] β†’ Dynamic content processing ↓ ↓ [db (MariaDB)] [redis-cache] @@ -68,10 +74,14 @@ Real-time: ### πŸ“ images/ - Docker Image Definitions -- **images/bench/** - Development container with full Frappe tooling and CLI -- **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 +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 [docs/container-setup/01-overview.md](container-setup/01-overview.md). ### πŸ“ overrides/ - Compose File Extensions @@ -419,7 +429,7 @@ images/*/Dockerfile # Core images - extend rather than modify ``` .github/workflows/ # CI/CD pipelines -images/production/ # Production containers +images/*/ # Core image definitions resources/ # Core templates ``` From 9e2fcc6fce15a9af9646ae47dc217b9f04caccab Mon Sep 17 00:00:00 2001 From: Asief Tejani <90562883+asieftejani@users.noreply.github.com> Date: Tue, 4 Nov 2025 12:13:16 +0300 Subject: [PATCH 043/279] changed customapps link --- compose.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compose.yaml b/compose.yaml index 7c8e64f2..9b8a2832 100644 --- a/compose.yaml +++ b/compose.yaml @@ -1,6 +1,6 @@ x-customizable-image: &customizable_image # By default the image used only contains the `frappe` and `erpnext` apps. - # See https://github.com/frappe/frappe_docker/blob/main/docs/custom-apps.md + # See https://github.com/frappe/frappe_docker/blob/main/docs/container-setup/02-build-setup.md # about using custom images. image: ${CUSTOM_IMAGE:-frappe/erpnext}:${CUSTOM_TAG:-$ERPNEXT_VERSION} pull_policy: ${PULL_POLICY:-always} From d6859180cd82dc33e60e690adaa909a8cd54014f Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 4 Nov 2025 13:08:44 +0000 Subject: [PATCH 044/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 8a2c509c..54744f16 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v15.85.1 +ERPNEXT_VERSION=v15.86.0 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index 97cc8844..37bf4cc5 100644 --- a/pwd.yml +++ b/pwd.yml @@ -2,7 +2,7 @@ version: "3" services: backend: - image: frappe/erpnext:v15.85.1 + image: frappe/erpnext:v15.86.0 networks: - frappe_network deploy: @@ -18,7 +18,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v15.85.1 + image: frappe/erpnext:v15.86.0 networks: - frappe_network deploy: @@ -47,7 +47,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v15.85.1 + image: frappe/erpnext:v15.86.0 networks: - frappe_network deploy: @@ -102,7 +102,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v15.85.1 + image: frappe/erpnext:v15.86.0 networks: - frappe_network depends_on: @@ -128,7 +128,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v15.85.1 + image: frappe/erpnext:v15.86.0 networks: - frappe_network deploy: @@ -147,7 +147,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v15.85.1 + image: frappe/erpnext:v15.86.0 networks: - frappe_network deploy: @@ -184,7 +184,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v15.85.1 + image: frappe/erpnext:v15.86.0 networks: - frappe_network deploy: @@ -198,7 +198,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v15.85.1 + image: frappe/erpnext:v15.86.0 networks: - frappe_network deploy: From 473081a2add3f01aedc59c73408c26d583c2a0e4 Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 5 Nov 2025 13:12:32 +0000 Subject: [PATCH 045/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 54744f16..0a99eb8b 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v15.86.0 +ERPNEXT_VERSION=v15.87.0 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index 37bf4cc5..e0366b04 100644 --- a/pwd.yml +++ b/pwd.yml @@ -2,7 +2,7 @@ version: "3" services: backend: - image: frappe/erpnext:v15.86.0 + image: frappe/erpnext:v15.87.0 networks: - frappe_network deploy: @@ -18,7 +18,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v15.86.0 + image: frappe/erpnext:v15.87.0 networks: - frappe_network deploy: @@ -47,7 +47,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v15.86.0 + image: frappe/erpnext:v15.87.0 networks: - frappe_network deploy: @@ -102,7 +102,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v15.86.0 + image: frappe/erpnext:v15.87.0 networks: - frappe_network depends_on: @@ -128,7 +128,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v15.86.0 + image: frappe/erpnext:v15.87.0 networks: - frappe_network deploy: @@ -147,7 +147,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v15.86.0 + image: frappe/erpnext:v15.87.0 networks: - frappe_network deploy: @@ -184,7 +184,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v15.86.0 + image: frappe/erpnext:v15.87.0 networks: - frappe_network deploy: @@ -198,7 +198,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v15.86.0 + image: frappe/erpnext:v15.87.0 networks: - frappe_network deploy: From f770253b896d04c417bf8edef6ddf22106d9096a Mon Sep 17 00:00:00 2001 From: Amanuel Elhanan <69236638+elhananjair@users.noreply.github.com> Date: Fri, 7 Nov 2025 11:26:40 +0300 Subject: [PATCH 046/279] Changing type of DB_PORT to string A value for DB_PORT must be a string for the podman-compose to work. --- overrides/compose.mariadb.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/overrides/compose.mariadb.yaml b/overrides/compose.mariadb.yaml index 22d95ea5..e79288c0 100644 --- a/overrides/compose.mariadb.yaml +++ b/overrides/compose.mariadb.yaml @@ -2,7 +2,7 @@ services: configurator: environment: DB_HOST: db - DB_PORT: 3306 + DB_PORT: "3306" depends_on: db: condition: service_healthy From bfeeee1cc00f2902f5a1f2b61ed24592fe742251 Mon Sep 17 00:00:00 2001 From: github-actions Date: Fri, 7 Nov 2025 17:11:13 +0000 Subject: [PATCH 047/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 0a99eb8b..2fac23fa 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v15.87.0 +ERPNEXT_VERSION=v15.87.1 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index e0366b04..4f93eaab 100644 --- a/pwd.yml +++ b/pwd.yml @@ -2,7 +2,7 @@ version: "3" services: backend: - image: frappe/erpnext:v15.87.0 + image: frappe/erpnext:v15.87.1 networks: - frappe_network deploy: @@ -18,7 +18,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v15.87.0 + image: frappe/erpnext:v15.87.1 networks: - frappe_network deploy: @@ -47,7 +47,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v15.87.0 + image: frappe/erpnext:v15.87.1 networks: - frappe_network deploy: @@ -102,7 +102,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v15.87.0 + image: frappe/erpnext:v15.87.1 networks: - frappe_network depends_on: @@ -128,7 +128,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v15.87.0 + image: frappe/erpnext:v15.87.1 networks: - frappe_network deploy: @@ -147,7 +147,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v15.87.0 + image: frappe/erpnext:v15.87.1 networks: - frappe_network deploy: @@ -184,7 +184,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v15.87.0 + image: frappe/erpnext:v15.87.1 networks: - frappe_network deploy: @@ -198,7 +198,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v15.87.0 + image: frappe/erpnext:v15.87.1 networks: - frappe_network deploy: From 8b84b7a96719ef417324702002d6cd6d6868c224 Mon Sep 17 00:00:00 2001 From: github-actions Date: Mon, 10 Nov 2025 11:22:23 +0000 Subject: [PATCH 048/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 2fac23fa..50f7f7f9 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v15.87.1 +ERPNEXT_VERSION=v15.87.2 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index 4f93eaab..c769d87e 100644 --- a/pwd.yml +++ b/pwd.yml @@ -2,7 +2,7 @@ version: "3" services: backend: - image: frappe/erpnext:v15.87.1 + image: frappe/erpnext:v15.87.2 networks: - frappe_network deploy: @@ -18,7 +18,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v15.87.1 + image: frappe/erpnext:v15.87.2 networks: - frappe_network deploy: @@ -47,7 +47,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v15.87.1 + image: frappe/erpnext:v15.87.2 networks: - frappe_network deploy: @@ -102,7 +102,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v15.87.1 + image: frappe/erpnext:v15.87.2 networks: - frappe_network depends_on: @@ -128,7 +128,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v15.87.1 + image: frappe/erpnext:v15.87.2 networks: - frappe_network deploy: @@ -147,7 +147,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v15.87.1 + image: frappe/erpnext:v15.87.2 networks: - frappe_network deploy: @@ -184,7 +184,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v15.87.1 + image: frappe/erpnext:v15.87.2 networks: - frappe_network deploy: @@ -198,7 +198,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v15.87.1 + image: frappe/erpnext:v15.87.2 networks: - frappe_network deploy: From cb2d0226f7a88273fd8d448f358d9f23c02ec527 Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 11 Nov 2025 15:16:56 +0000 Subject: [PATCH 049/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 50f7f7f9..0f63e40a 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v15.87.2 +ERPNEXT_VERSION=v15.88.0 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index c769d87e..4df0b1c9 100644 --- a/pwd.yml +++ b/pwd.yml @@ -2,7 +2,7 @@ version: "3" services: backend: - image: frappe/erpnext:v15.87.2 + image: frappe/erpnext:v15.88.0 networks: - frappe_network deploy: @@ -18,7 +18,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v15.87.2 + image: frappe/erpnext:v15.88.0 networks: - frappe_network deploy: @@ -47,7 +47,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v15.87.2 + image: frappe/erpnext:v15.88.0 networks: - frappe_network deploy: @@ -102,7 +102,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v15.87.2 + image: frappe/erpnext:v15.88.0 networks: - frappe_network depends_on: @@ -128,7 +128,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v15.87.2 + image: frappe/erpnext:v15.88.0 networks: - frappe_network deploy: @@ -147,7 +147,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v15.87.2 + image: frappe/erpnext:v15.88.0 networks: - frappe_network deploy: @@ -184,7 +184,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v15.87.2 + image: frappe/erpnext:v15.88.0 networks: - frappe_network deploy: @@ -198,7 +198,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v15.87.2 + image: frappe/erpnext:v15.88.0 networks: - frappe_network deploy: From 7ccb3098963b5ccf6aa2b2086fc7530d9a571d88 Mon Sep 17 00:00:00 2001 From: duthink Date: Wed, 12 Nov 2025 12:00:55 +0530 Subject: [PATCH 050/279] fix: update custom app doc link --- compose.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compose.yaml b/compose.yaml index 7c8e64f2..edf406ca 100644 --- a/compose.yaml +++ b/compose.yaml @@ -1,6 +1,6 @@ x-customizable-image: &customizable_image # By default the image used only contains the `frappe` and `erpnext` apps. - # See https://github.com/frappe/frappe_docker/blob/main/docs/custom-apps.md + # See https://github.com/frappe/frappe_docker/blob/main/docs/container-setup/02-build-setup.md#define-custom-apps # about using custom images. image: ${CUSTOM_IMAGE:-frappe/erpnext}:${CUSTOM_TAG:-$ERPNEXT_VERSION} pull_policy: ${PULL_POLICY:-always} From 1a799ee4da2c2058c82d55a4fa74fced7abcdca9 Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 12 Nov 2025 19:00:48 +0000 Subject: [PATCH 051/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 0f63e40a..74174834 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v15.88.0 +ERPNEXT_VERSION=v15.88.1 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index 4df0b1c9..7dfeae15 100644 --- a/pwd.yml +++ b/pwd.yml @@ -2,7 +2,7 @@ version: "3" services: backend: - image: frappe/erpnext:v15.88.0 + image: frappe/erpnext:v15.88.1 networks: - frappe_network deploy: @@ -18,7 +18,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v15.88.0 + image: frappe/erpnext:v15.88.1 networks: - frappe_network deploy: @@ -47,7 +47,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v15.88.0 + image: frappe/erpnext:v15.88.1 networks: - frappe_network deploy: @@ -102,7 +102,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v15.88.0 + image: frappe/erpnext:v15.88.1 networks: - frappe_network depends_on: @@ -128,7 +128,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v15.88.0 + image: frappe/erpnext:v15.88.1 networks: - frappe_network deploy: @@ -147,7 +147,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v15.88.0 + image: frappe/erpnext:v15.88.1 networks: - frappe_network deploy: @@ -184,7 +184,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v15.88.0 + image: frappe/erpnext:v15.88.1 networks: - frappe_network deploy: @@ -198,7 +198,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v15.88.0 + image: frappe/erpnext:v15.88.1 networks: - frappe_network deploy: From 7a2eff02773faddc8c04e70a701298db4f41f794 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 13 Nov 2025 08:03:43 +0000 Subject: [PATCH 052/279] chore(deps): bump pytest from 8.4.2 to 9.0.1 Bumps [pytest](https://github.com/pytest-dev/pytest) from 8.4.2 to 9.0.1. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/8.4.2...9.0.1) --- updated-dependencies: - dependency-name: pytest dependency-version: 9.0.1 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- requirements-test.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-test.txt b/requirements-test.txt index 9471b3d9..02559c42 100644 --- a/requirements-test.txt +++ b/requirements-test.txt @@ -1 +1 @@ -pytest==8.4.2 +pytest==9.0.1 From 7a9c09b045a7c620c5a8b01c461cdf8485777f28 Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 19 Nov 2025 03:32:39 +0000 Subject: [PATCH 053/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 74174834..3d735f00 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v15.88.1 +ERPNEXT_VERSION=v15.89.0 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index 7dfeae15..5d7b9ff0 100644 --- a/pwd.yml +++ b/pwd.yml @@ -2,7 +2,7 @@ version: "3" services: backend: - image: frappe/erpnext:v15.88.1 + image: frappe/erpnext:v15.89.0 networks: - frappe_network deploy: @@ -18,7 +18,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v15.88.1 + image: frappe/erpnext:v15.89.0 networks: - frappe_network deploy: @@ -47,7 +47,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v15.88.1 + image: frappe/erpnext:v15.89.0 networks: - frappe_network deploy: @@ -102,7 +102,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v15.88.1 + image: frappe/erpnext:v15.89.0 networks: - frappe_network depends_on: @@ -128,7 +128,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v15.88.1 + image: frappe/erpnext:v15.89.0 networks: - frappe_network deploy: @@ -147,7 +147,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v15.88.1 + image: frappe/erpnext:v15.89.0 networks: - frappe_network deploy: @@ -184,7 +184,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v15.88.1 + image: frappe/erpnext:v15.89.0 networks: - frappe_network deploy: @@ -198,7 +198,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v15.88.1 + image: frappe/erpnext:v15.89.0 networks: - frappe_network deploy: From 090f74617a45e7d66ef884f1ad311b4d7c979b56 Mon Sep 17 00:00:00 2001 From: "daniel.radl" Date: Wed, 19 Nov 2025 15:07:18 +0100 Subject: [PATCH 054/279] feat: added v16 docker images --- .github/scripts/get_latest_tags.py | 4 ++-- .github/workflows/build_stable.yml | 12 ++++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/.github/scripts/get_latest_tags.py b/.github/scripts/get_latest_tags.py index 7d168bab..2eb62fb7 100644 --- a/.github/scripts/get_latest_tags.py +++ b/.github/scripts/get_latest_tags.py @@ -9,7 +9,7 @@ import sys from typing import Literal Repo = Literal["frappe", "erpnext"] -MajorVersion = Literal["12", "13", "14", "15", "develop"] +MajorVersion = Literal["12", "13", "14", "15", "16", "develop"] def get_latest_tag(repo: Repo, version: MajorVersion) -> str: @@ -57,7 +57,7 @@ def main(_args: list[str]) -> int: parser = argparse.ArgumentParser() parser.add_argument("--repo", choices=["frappe", "erpnext"], required=True) parser.add_argument( - "--version", choices=["12", "13", "14", "15", "develop"], required=True + "--version", choices=["12", "13", "14", "15", "16", "develop"], required=True ) args = parser.parse_args(_args) diff --git a/.github/workflows/build_stable.yml b/.github/workflows/build_stable.yml index 6ddbb0ea..dc58a110 100644 --- a/.github/workflows/build_stable.yml +++ b/.github/workflows/build_stable.yml @@ -54,6 +54,18 @@ jobs: DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }} DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} + v16: + uses: ./.github/workflows/docker-build-push.yml + with: + repo: erpnext + version: "16" + push: ${{ github.repository == 'frappe/frappe_docker' && github.event_name != 'pull_request' }} + python_version: 3.12.12 + node_version: 22.21.1 + secrets: + DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }} + DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} + update_versions: name: Update example.env and pwd.yml runs-on: ubuntu-latest From 17dda594ad52d4f08b8717640901699875723b29 Mon Sep 17 00:00:00 2001 From: github-actions Date: Fri, 21 Nov 2025 11:12:35 +0000 Subject: [PATCH 055/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 3d735f00..ad078b30 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v15.89.0 +ERPNEXT_VERSION=v15.89.1 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index 5d7b9ff0..3b14e183 100644 --- a/pwd.yml +++ b/pwd.yml @@ -2,7 +2,7 @@ version: "3" services: backend: - image: frappe/erpnext:v15.89.0 + image: frappe/erpnext:v15.89.1 networks: - frappe_network deploy: @@ -18,7 +18,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v15.89.0 + image: frappe/erpnext:v15.89.1 networks: - frappe_network deploy: @@ -47,7 +47,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v15.89.0 + image: frappe/erpnext:v15.89.1 networks: - frappe_network deploy: @@ -102,7 +102,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v15.89.0 + image: frappe/erpnext:v15.89.1 networks: - frappe_network depends_on: @@ -128,7 +128,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v15.89.0 + image: frappe/erpnext:v15.89.1 networks: - frappe_network deploy: @@ -147,7 +147,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v15.89.0 + image: frappe/erpnext:v15.89.1 networks: - frappe_network deploy: @@ -184,7 +184,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v15.89.0 + image: frappe/erpnext:v15.89.1 networks: - frappe_network deploy: @@ -198,7 +198,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v15.89.0 + image: frappe/erpnext:v15.89.1 networks: - frappe_network deploy: From f5479464753a2ca43c8f700da38a3b7f9d92752e Mon Sep 17 00:00:00 2001 From: github-actions Date: Fri, 21 Nov 2025 18:09:50 +0000 Subject: [PATCH 056/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index ad078b30..bae0b00e 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v15.89.1 +ERPNEXT_VERSION=v15.89.2 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index 3b14e183..9505ad0d 100644 --- a/pwd.yml +++ b/pwd.yml @@ -2,7 +2,7 @@ version: "3" services: backend: - image: frappe/erpnext:v15.89.1 + image: frappe/erpnext:v15.89.2 networks: - frappe_network deploy: @@ -18,7 +18,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v15.89.1 + image: frappe/erpnext:v15.89.2 networks: - frappe_network deploy: @@ -47,7 +47,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v15.89.1 + image: frappe/erpnext:v15.89.2 networks: - frappe_network deploy: @@ -102,7 +102,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v15.89.1 + image: frappe/erpnext:v15.89.2 networks: - frappe_network depends_on: @@ -128,7 +128,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v15.89.1 + image: frappe/erpnext:v15.89.2 networks: - frappe_network deploy: @@ -147,7 +147,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v15.89.1 + image: frappe/erpnext:v15.89.2 networks: - frappe_network deploy: @@ -184,7 +184,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v15.89.1 + image: frappe/erpnext:v15.89.2 networks: - frappe_network deploy: @@ -198,7 +198,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v15.89.1 + image: frappe/erpnext:v15.89.2 networks: - frappe_network deploy: From b4a67001670b7ab06b4ba00439694e3ad028c538 Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 25 Nov 2025 15:37:28 +0000 Subject: [PATCH 057/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index bae0b00e..f2bcb3b9 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v15.89.2 +ERPNEXT_VERSION=v15.90.0 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index 9505ad0d..b2b9e582 100644 --- a/pwd.yml +++ b/pwd.yml @@ -2,7 +2,7 @@ version: "3" services: backend: - image: frappe/erpnext:v15.89.2 + image: frappe/erpnext:v15.90.0 networks: - frappe_network deploy: @@ -18,7 +18,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v15.89.2 + image: frappe/erpnext:v15.90.0 networks: - frappe_network deploy: @@ -47,7 +47,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v15.89.2 + image: frappe/erpnext:v15.90.0 networks: - frappe_network deploy: @@ -102,7 +102,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v15.89.2 + image: frappe/erpnext:v15.90.0 networks: - frappe_network depends_on: @@ -128,7 +128,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v15.89.2 + image: frappe/erpnext:v15.90.0 networks: - frappe_network deploy: @@ -147,7 +147,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v15.89.2 + image: frappe/erpnext:v15.90.0 networks: - frappe_network deploy: @@ -184,7 +184,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v15.89.2 + image: frappe/erpnext:v15.90.0 networks: - frappe_network deploy: @@ -198,7 +198,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v15.89.2 + image: frappe/erpnext:v15.90.0 networks: - frappe_network deploy: From d8a917e5bd3b853eaafc7d905431a99a8ad38d4a Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 26 Nov 2025 09:47:24 +0000 Subject: [PATCH 058/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index f2bcb3b9..76656512 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v15.90.0 +ERPNEXT_VERSION=v15.90.1 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index b2b9e582..4bdee9fd 100644 --- a/pwd.yml +++ b/pwd.yml @@ -2,7 +2,7 @@ version: "3" services: backend: - image: frappe/erpnext:v15.90.0 + image: frappe/erpnext:v15.90.1 networks: - frappe_network deploy: @@ -18,7 +18,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v15.90.0 + image: frappe/erpnext:v15.90.1 networks: - frappe_network deploy: @@ -47,7 +47,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v15.90.0 + image: frappe/erpnext:v15.90.1 networks: - frappe_network deploy: @@ -102,7 +102,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v15.90.0 + image: frappe/erpnext:v15.90.1 networks: - frappe_network depends_on: @@ -128,7 +128,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v15.90.0 + image: frappe/erpnext:v15.90.1 networks: - frappe_network deploy: @@ -147,7 +147,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v15.90.0 + image: frappe/erpnext:v15.90.1 networks: - frappe_network deploy: @@ -184,7 +184,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v15.90.0 + image: frappe/erpnext:v15.90.1 networks: - frappe_network deploy: @@ -198,7 +198,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v15.90.0 + image: frappe/erpnext:v15.90.1 networks: - frappe_network deploy: From 5a535cc8fafa7a6eed3a8a4cd13fb64ef5ef8ec1 Mon Sep 17 00:00:00 2001 From: Daniel Radl Date: Wed, 26 Nov 2025 13:08:31 +0100 Subject: [PATCH 059/279] feat(devcontainer): Add mariadb driver and connection settings actually make use of the already installed sqltools --- devcontainer-example/devcontainer.json | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/devcontainer-example/devcontainer.json b/devcontainer-example/devcontainer.json index 2e60f65d..c5fceddc 100644 --- a/devcontainer-example/devcontainer.json +++ b/devcontainer-example/devcontainer.json @@ -9,6 +9,7 @@ "ms-vscode.live-server", "grapecity.gc-excelviewer", "mtxr.sqltools", + "mtxr.sqltools-driver-mysql", "visualstudioexptteam.vscodeintellicode" ], "settings": { @@ -18,7 +19,24 @@ } }, "terminal.integrated.defaultProfile.linux": "frappe bash", - "debug.node.autoAttach": "disabled" + "debug.node.autoAttach": "disabled", + "sqltools.connections": [ + { + "mysqlOptions": { + "authProtocol": "default", + "enableSsl": "Disabled" + }, + "ssh": "Disabled", + "previewLimit": 50, + "server": "mariadb", + "port": 3306, + "driver": "MariaDB", + "name": "MariaDB", + "username": "root", + "password": "123", + "database": "mysql" + } + ] } } }, From 46b2643e4ca23fb8ca26c4441e4f3ddedcb70cce Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 2 Dec 2025 17:07:33 +0000 Subject: [PATCH 060/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 76656512..3aeb05d2 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v15.90.1 +ERPNEXT_VERSION=v15.91.0 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index 4bdee9fd..f00f973d 100644 --- a/pwd.yml +++ b/pwd.yml @@ -2,7 +2,7 @@ version: "3" services: backend: - image: frappe/erpnext:v15.90.1 + image: frappe/erpnext:v15.91.0 networks: - frappe_network deploy: @@ -18,7 +18,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v15.90.1 + image: frappe/erpnext:v15.91.0 networks: - frappe_network deploy: @@ -47,7 +47,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v15.90.1 + image: frappe/erpnext:v15.91.0 networks: - frappe_network deploy: @@ -102,7 +102,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v15.90.1 + image: frappe/erpnext:v15.91.0 networks: - frappe_network depends_on: @@ -128,7 +128,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v15.90.1 + image: frappe/erpnext:v15.91.0 networks: - frappe_network deploy: @@ -147,7 +147,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v15.90.1 + image: frappe/erpnext:v15.91.0 networks: - frappe_network deploy: @@ -184,7 +184,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v15.90.1 + image: frappe/erpnext:v15.91.0 networks: - frappe_network deploy: @@ -198,7 +198,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v15.90.1 + image: frappe/erpnext:v15.91.0 networks: - frappe_network deploy: From 2bd0189791d6c3adcce35bff8d5be9333ba456f2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 5 Dec 2025 09:53:13 +0530 Subject: [PATCH 061/279] chore(deps): bump actions/checkout from 5 to 6 (#1752) Bumps [actions/checkout](https://github.com/actions/checkout) from 5 to 6. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v5...v6) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build_bench.yml | 2 +- .github/workflows/build_stable.yml | 2 +- .github/workflows/docker-build-push.yml | 2 +- .github/workflows/lint.yml | 2 +- .github/workflows/pre-commit-autoupdate.yml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build_bench.yml b/.github/workflows/build_bench.yml index 1835f1c3..5639f505 100644 --- a/.github/workflows/build_bench.yml +++ b/.github/workflows/build_bench.yml @@ -20,7 +20,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v5 + uses: actions/checkout@v6 - name: Setup QEMU uses: docker/setup-qemu-action@v3 diff --git a/.github/workflows/build_stable.yml b/.github/workflows/build_stable.yml index dc58a110..01c0eed6 100644 --- a/.github/workflows/build_stable.yml +++ b/.github/workflows/build_stable.yml @@ -74,7 +74,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v5 + uses: actions/checkout@v6 - name: Setup Python uses: actions/setup-python@v6 diff --git a/.github/workflows/docker-build-push.yml b/.github/workflows/docker-build-push.yml index d17dbf9e..8fda78cc 100644 --- a/.github/workflows/docker-build-push.yml +++ b/.github/workflows/docker-build-push.yml @@ -43,7 +43,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v5 + uses: actions/checkout@v6 - name: Setup QEMU uses: docker/setup-qemu-action@v3 diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 6f72e86b..3d9ec5cb 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v5 + uses: actions/checkout@v6 - name: Setup Python uses: actions/setup-python@v6 diff --git a/.github/workflows/pre-commit-autoupdate.yml b/.github/workflows/pre-commit-autoupdate.yml index 29a5b5af..a8ef378d 100644 --- a/.github/workflows/pre-commit-autoupdate.yml +++ b/.github/workflows/pre-commit-autoupdate.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v5 + uses: actions/checkout@v6 - name: Update pre-commit hooks uses: vrslev/pre-commit-autoupdate@v1.0.0 From df2ce36cb30ffd2b9f4857fb3bb290656085844a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 5 Dec 2025 09:53:30 +0530 Subject: [PATCH 062/279] chore(deps): bump docker/bake-action from 6.9.0 to 6.10.0 (#1755) Bumps [docker/bake-action](https://github.com/docker/bake-action) from 6.9.0 to 6.10.0. - [Release notes](https://github.com/docker/bake-action/releases) - [Commits](https://github.com/docker/bake-action/compare/v6.9.0...v6.10.0) --- updated-dependencies: - dependency-name: docker/bake-action dependency-version: 6.10.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build_bench.yml | 4 ++-- .github/workflows/docker-build-push.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build_bench.yml b/.github/workflows/build_bench.yml index 5639f505..48b4f818 100644 --- a/.github/workflows/build_bench.yml +++ b/.github/workflows/build_bench.yml @@ -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.9.0 + uses: docker/bake-action@v6.10.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.9.0 + uses: docker/bake-action@v6.10.0 with: targets: bench push: true diff --git a/.github/workflows/docker-build-push.yml b/.github/workflows/docker-build-push.yml index 8fda78cc..a90f784e 100644 --- a/.github/workflows/docker-build-push.yml +++ b/.github/workflows/docker-build-push.yml @@ -66,7 +66,7 @@ jobs: echo "NODE_VERSION=${{ inputs.node_version }}" >> "$GITHUB_ENV" - name: Build - uses: docker/bake-action@v6.9.0 + uses: docker/bake-action@v6.10.0 with: source: . push: true @@ -95,7 +95,7 @@ jobs: - name: Push if: ${{ inputs.push }} - uses: docker/bake-action@v6.9.0 + uses: docker/bake-action@v6.10.0 with: push: true set: "*.platform=linux/amd64,linux/arm64" From 09934d576c5c84f70b8bddfae4ebae9f963d344c Mon Sep 17 00:00:00 2001 From: Ali Al Saif <78873652+0x1B40@users.noreply.github.com> Date: Sat, 6 Dec 2025 07:37:36 +0300 Subject: [PATCH 063/279] docs: reorganize documentation structure with numbered navigation (#1729) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: reorganize documentation structure into logical categories Restructure documentation into organized directories for better navigation: - getting-started/: Quick start guides for new users - setup/: Setup and configuration guides - production/: Production deployment guides (backup, TLS, multi-tenancy) - operations/: Site operations and management - development/: Development workflow guides - migration/: Migration guides - troubleshooting/: Troubleshooting guides - reference/: Reference documentation (container setup, build configs) Rename files for consistency: - Use kebab-case naming convention throughout - Remove numbered prefixes from container-setup files - Use descriptive names (backup-strategy, tls-ssl-setup, etc.) Update all internal cross-references to reflect new file locations. Update README.md with organized documentation structure. Fix image paths in development.md to use correct relative paths. * docs: add numeric prefixes to directories and files for navigation order Add numeric prefixes (01-08) to documentation directories to indicate reading order and flow for first-time users: - 01-getting-started: Quick start guides - 02-setup: Setup and configuration - 03-production: Production deployment - 04-operations: Site operations - 05-development: Development guides - 06-migration: Migration guides - 07-troubleshooting: Troubleshooting - 08-reference: Reference documentation Add numeric prefixes to files within directories to guide readers through documentation in a logical sequence. Update all cross-references throughout documentation to use new numbered paths. Update README.md to reflect the new structure. * docs: move container-setup to 02-setup and integrate setup-options content Move container-setup directory from 08-reference/ to 02-setup/ to follow PR feedback. The container-setup documentation provides a more linear and coherent flow compared to the previous unstructured setup files. Changes: - Move container-setup/ from docs/08-reference/ to docs/02-setup/ - Integrate content from setup-options.md into structured flow: - Create new 06-setup-examples.md with practical deployment scenarios - Enhance 03-start-setup.md with site creation details from setup-options - Remove redundant 01-setup-options.md (content now integrated) - Rename 02-single-server-example.md to 07-single-server-example.md - Update all cross-references throughout documentation: - Update README.md with new structure under Setup section - Fix links in site-operations.md and migration docs - Add navigation links between container-setup files and examples - Maintain container-setup's linear flow: overview β†’ build β†’ start β†’ env β†’ overrides - Add practical examples document (06-setup-examples.md) that follows the container-setup guide Result: Documentation now follows a clear progression from conceptual overview through practical examples, with all setup information properly organized under 02-setup/. * docs: remove container-setup subfolder and flatten structure Move all files from docs/02-setup/container-setup/ directly into docs/02-setup/ to eliminate unnecessary subfolder. Files are already numbered sequentially, so they work perfectly at the same level. Changes: - Move all files from container-setup/ subfolder to 02-setup/ root - Remove container-setup/ subfolder - Update all cross-references: - Update README.md paths (remove container-setup/ from all links) - Fix references in site-operations.md - Fix references in migration docs - Update internal references in 06-setup-examples.md - Fix relative path references in 01-overview.md, 02-build-setup.md, 03-start-setup.md Result: Cleaner, flatter structure with all numbered setup files at the same level, making navigation more straightforward. * fix: Pre-commit failure is fixed --------- Co-authored-by: adithya --- README.md | 53 ++++--- .../01-quick-start-linux-mac.md} | 0 .../02-single-compose-setup.md} | 0 .../01-overview.md | 4 +- .../02-build-setup.md | 4 +- .../03-start-setup.md | 20 +++ .../04-env-variables.md} | 0 .../overrider.md => 02-setup/05-overrides.md} | 0 docs/02-setup/06-setup-examples.md | 138 ++++++++++++++++++ .../07-single-server-example.md} | 10 +- .../01-tls-ssl-setup.md} | 0 .../02-backup-strategy.md} | 0 .../03-multi-tenancy.md} | 0 .../01-site-operations.md} | 2 +- .../01-development.md} | 4 +- .../02-debugging.md} | 0 .../03-local-services-connection.md} | 0 .../01-migrate-from-multi-image-setup.md} | 2 +- .../01-troubleshoot.md} | 0 .../02-windows-nginx-entrypoint-error.md} | 0 .../01-build-version-10-images.md} | 0 docs/setup-options.md | 131 ----------------- 22 files changed, 211 insertions(+), 157 deletions(-) rename docs/{setup_for_linux_mac.md => 01-getting-started/01-quick-start-linux-mac.md} (100%) rename docs/{single-compose-setup.md => 01-getting-started/02-single-compose-setup.md} (100%) rename docs/{container-setup => 02-setup}/01-overview.md (96%) rename docs/{container-setup => 02-setup}/02-build-setup.md (95%) rename docs/{container-setup => 02-setup}/03-start-setup.md (73%) rename docs/{container-setup/env-variables.md => 02-setup/04-env-variables.md} (100%) rename docs/{container-setup/overrider.md => 02-setup/05-overrides.md} (100%) create mode 100644 docs/02-setup/06-setup-examples.md rename docs/{single-server-example.md => 02-setup/07-single-server-example.md} (97%) rename docs/{tls-for-local-deployment.md => 03-production/01-tls-ssl-setup.md} (100%) rename docs/{backup-and-push-cronjob.md => 03-production/02-backup-strategy.md} (100%) rename docs/{port-based-multi-tenancy.md => 03-production/03-multi-tenancy.md} (100%) rename docs/{site-operations.md => 04-operations/01-site-operations.md} (95%) rename docs/{development.md => 05-development/01-development.md} (99%) rename docs/{bench-console-and-vscode-debugger.md => 05-development/02-debugging.md} (100%) rename docs/{connect-to-localhost-services-from-containers-for-local-app-development.md => 05-development/03-local-services-connection.md} (100%) rename docs/{migrate-from-multi-image-setup.md => 06-migration/01-migrate-from-multi-image-setup.md} (98%) rename docs/{troubleshoot.md => 07-troubleshooting/01-troubleshoot.md} (100%) rename docs/{error-nginx-entrypoint-windows.md => 07-troubleshooting/02-windows-nginx-entrypoint-error.md} (100%) rename docs/{build-version-10-images.md => 08-reference/01-build-version-10-images.md} (100%) delete mode 100644 docs/setup-options.md diff --git a/README.md b/README.md index 6a208926..1296dd5d 100644 --- a/README.md +++ b/README.md @@ -55,32 +55,49 @@ If you ran in a Dev Docker environment, to view container logs: `docker compose ### [Frequently Asked Questions](https://github.com/frappe/frappe_docker/wiki/Frequently-Asked-Questions) +### [Getting Started](#getting-started) + +- [Quick Start (Linux/Mac)](docs/01-getting-started/01-quick-start-linux-mac.md) +- [Single Compose Setup](docs/01-getting-started/02-single-compose-setup.md) + +### [Setup](#setup) + +- [Container Setup Overview](docs/02-setup/01-overview.md) +- [Build Setup](docs/02-setup/02-build-setup.md) +- [Start Setup](docs/02-setup/03-start-setup.md) +- [Environment Variables](docs/02-setup/04-env-variables.md) +- [Compose Overrides](docs/02-setup/05-overrides.md) +- [Setup Examples](docs/02-setup/06-setup-examples.md) +- [Single Server Example](docs/02-setup/07-single-server-example.md) + ### [Production](#production) -- [List of containers](docs/container-setup/01-overview.md) -- [Single Compose Setup](docs/single-compose-setup.md) -- [Environment Variables](docs/container-setup/env-variables.md) -- [Single Server Example](docs/single-server-example.md) -- [Setup Options](docs/setup-options.md) -- [Site Operations](docs/site-operations.md) -- [Backup and Push Cron Job](docs/backup-and-push-cronjob.md) -- [Port Based Multi Tenancy](docs/port-based-multi-tenancy.md) -- [Migrate from multi-image setup](docs/migrate-from-multi-image-setup.md) -- [running on linux/mac](docs/setup_for_linux_mac.md) -- [TLS for local deployment](docs/tls-for-local-deployment.md) +- [TLS/SSL Setup](docs/03-production/01-tls-ssl-setup.md) +- [Backup Strategy](docs/03-production/02-backup-strategy.md) +- [Multi-Tenancy](docs/03-production/03-multi-tenancy.md) -### [Custom Images](#custom-images) +### [Operations](#operations) -- [Custom Apps](docs/container-setup/02-build-setup.md) -- [Build Version 10 Images](docs/build-version-10-images.md) +- [Site Operations](docs/04-operations/01-site-operations.md) ### [Development](#development) -- [Development using containers](docs/development.md) -- [Bench Console and VSCode Debugger](docs/bench-console-and-vscode-debugger.md) -- [Connect to localhost services](docs/connect-to-localhost-services-from-containers-for-local-app-development.md) +- [Development Guide](docs/05-development/01-development.md) +- [Debugging](docs/05-development/02-debugging.md) +- [Local Services Connection](docs/05-development/03-local-services-connection.md) -### [Troubleshoot](docs/troubleshoot.md) +### [Migration](#migration) + +- [Migrate from Multi-Image Setup](docs/06-migration/01-migrate-from-multi-image-setup.md) + +### [Troubleshooting](#troubleshooting) + +- [Troubleshoot Guide](docs/07-troubleshooting/01-troubleshoot.md) +- [Windows Nginx Entrypoint Error](docs/07-troubleshooting/02-windows-nginx-entrypoint-error.md) + +### [Reference](#reference) + +- [Build Version 10 Images](docs/08-reference/01-build-version-10-images.md) # Contributing diff --git a/docs/setup_for_linux_mac.md b/docs/01-getting-started/01-quick-start-linux-mac.md similarity index 100% rename from docs/setup_for_linux_mac.md rename to docs/01-getting-started/01-quick-start-linux-mac.md diff --git a/docs/single-compose-setup.md b/docs/01-getting-started/02-single-compose-setup.md similarity index 100% rename from docs/single-compose-setup.md rename to docs/01-getting-started/02-single-compose-setup.md diff --git a/docs/container-setup/01-overview.md b/docs/02-setup/01-overview.md similarity index 96% rename from docs/container-setup/01-overview.md rename to docs/02-setup/01-overview.md index ee266886..08f3d233 100644 --- a/docs/container-setup/01-overview.md +++ b/docs/02-setup/01-overview.md @@ -40,8 +40,10 @@ Once images are built, containers are orchestrated using a [compose file](https: Additional functionality can be added using [overrides](https://docs.docker.com/compose/extends/). These files modify existing services or add new ones without changing the main `compose.yaml`. -Example: The main compose file has no database service, but `compose.mariadb.yaml` adds MariaDB. See [overrider.md](overrider.md) for the complete list of available overrides and how to use them. +Example: The main compose file has no database service, but `compose.mariadb.yaml` adds MariaDB. See [overrides.md](05-overrides.md) for the complete list of available overrides and how to use them. --- **Next:** [Build Setup β†’](02-build-setup.md) + +**See also:** [Setup Examples](06-setup-examples.md) for practical deployment scenarios. diff --git a/docs/container-setup/02-build-setup.md b/docs/02-setup/02-build-setup.md similarity index 95% rename from docs/container-setup/02-build-setup.md rename to docs/02-setup/02-build-setup.md index 0e3f0e36..ace05f49 100644 --- a/docs/container-setup/02-build-setup.md +++ b/docs/02-setup/02-build-setup.md @@ -95,7 +95,7 @@ The compose file requires several environment variables. You can either export t cp example.env custom.env ``` -Edit `custom.env` to customize variables for your setup. The template includes common variables, but you can add, modify, or remove any as needed. See [env-variables.md](env-variables.md) for detailed descriptions of all available variables. +Edit `custom.env` to customize variables for your setup. The template includes common variables, but you can add, modify, or remove any as needed. See [env-variables.md](04-env-variables.md) for detailed descriptions of all available variables. # Creating the final compose file @@ -119,3 +119,5 @@ This generates `compose.custom.yaml`, which you'll use to start all containers. **Next:** [Start Setup β†’](03-start-setup.md) **Back:** [Container Overview ←](01-overview.md) + +**See also:** [Setup Examples](06-setup-examples.md) for practical deployment scenarios. diff --git a/docs/container-setup/03-start-setup.md b/docs/02-setup/03-start-setup.md similarity index 73% rename from docs/container-setup/03-start-setup.md rename to docs/02-setup/03-start-setup.md index e19df758..53dba44c 100644 --- a/docs/container-setup/03-start-setup.md +++ b/docs/02-setup/03-start-setup.md @@ -16,6 +16,8 @@ The `-p` (or `--project-name`) flag names the project `frappe`, allowing you to Frappe is now running, but it's not yet configured. You need to create a site and install your apps. +## Basic site creation + ```bash docker compose -p frappe exec backend bench new-site --mariadb-user-host-login-scope='172.%.%.%' docker compose -p frappe exec backend bench --site install-app erpnext @@ -29,6 +31,22 @@ bench --site install-app erpnext Replace `` with your desired site name. +## Create site with app installation + +You can install apps during site creation: + +```bash +docker compose -p frappe exec backend bench new-site \ + --mariadb-user-host-login-scope='%' \ + --db-root-password \ + --admin-password \ + --install-app erpnext +``` + +> **Note:** Wait for the `db` service to start and `configurator` to exit before trying to create a new site. Usually this takes up to 10 seconds. + +For more site operations, refer to [site operations](../../04-operations/01-site-operations.md). + > ## Understanding the MariaDB User Scope > > The flag --mariadb-user-host-login-scope='172.%.%.%' allows database connections from any IP address within the 172.0.0.0/8 range. This includes all containers and virtual machines running on your machine. @@ -40,3 +58,5 @@ Replace `` with your desired site name. --- **Back:** [Build Setup β†’](02-build-setup.md) + +**Next:** [Setup Examples β†’](06-setup-examples.md) diff --git a/docs/container-setup/env-variables.md b/docs/02-setup/04-env-variables.md similarity index 100% rename from docs/container-setup/env-variables.md rename to docs/02-setup/04-env-variables.md diff --git a/docs/container-setup/overrider.md b/docs/02-setup/05-overrides.md similarity index 100% rename from docs/container-setup/overrider.md rename to docs/02-setup/05-overrides.md diff --git a/docs/02-setup/06-setup-examples.md b/docs/02-setup/06-setup-examples.md new file mode 100644 index 00000000..becf9442 --- /dev/null +++ b/docs/02-setup/06-setup-examples.md @@ -0,0 +1,138 @@ +# Setup Examples + +This guide provides practical examples for common setup scenarios. These examples build upon the [container setup guide](01-overview.md) and demonstrate how to combine the base compose file with overrides. + +> **Note:** This setup is not for development. A complete development environment is available [here](../05-development/01-development.md). + +## Prerequisites + +- [docker](https://docker.com/get-started) +- [docker compose v2](https://docs.docker.com/compose/cli-command) +- Cloned `frappe_docker` repository + +## Setup Environment Variables + +Copy the example docker environment file to `.env`: + +```sh +cp example.env .env +``` + +Edit `.env` and set variables according to your needs. See [environment variables](04-env-variables.md) for detailed descriptions of all available variables. + +## Storing Generated YAML Files + +YAML files generated by `docker compose config` can be stored in a directory for version control and management: + +```shell +mkdir ~/gitops +``` + +You can make this directory into a private git repository to track changes to your configuration. This is especially useful for managing multiple environments or projects. + +Alternatively, you can directly use `docker compose up` to start containers without storing intermediate YAML files. + +## Example 1: Frappe without Proxy (Direct Access) + +Setup Frappe with containerized MariaDB and Redis, exposing the application directly on port `:8080` without a reverse proxy. + +**Requirements:** + +- Set `DB_PASSWORD` in `.env` (or use default `123`) +- No external database or Redis needed + +```sh +# Generate YAML +docker compose -f compose.yaml \ + -f overrides/compose.mariadb.yaml \ + -f overrides/compose.redis.yaml \ + -f overrides/compose.noproxy.yaml \ + config > ~/gitops/docker-compose.yml + +# Start containers +docker compose --project-name -f ~/gitops/docker-compose.yml up -d +``` + +## Example 2: ERPNext with External Database and Redis + +Setup ERPNext using external MariaDB and Redis instances with Traefik HTTP proxy. + +**Requirements:** + +- Set `DB_HOST`, `DB_PORT`, `REDIS_CACHE`, and `REDIS_QUEUE` in `.env` +- External database and Redis must be accessible + +```sh +# Generate YAML +docker compose -f compose.yaml \ + -f overrides/compose.proxy.yaml \ + config > ~/gitops/docker-compose.yml + +# Start containers +docker compose --project-name -f ~/gitops/docker-compose.yml up -d +``` + +## Example 3: Production Setup with HTTPS + +Setup Frappe/ERPNext using containerized MariaDB and Redis with Let's Encrypt SSL certificates via Traefik. + +**Requirements:** + +- Set `LETSENCRYPT_EMAIL` and `SITES` environment variables +- DNS must point to your server IP + +```sh +# Generate YAML +docker compose -f compose.yaml \ + -f overrides/compose.mariadb.yaml \ + -f overrides/compose.redis.yaml \ + -f overrides/compose.https.yaml \ + config > ~/gitops/docker-compose.yml + +# Start containers +docker compose --project-name -f ~/gitops/docker-compose.yml up -d +``` + +> **Note:** Ensure your `SITES` variable is properly formatted. See [environment variables](04-env-variables.md) for the correct format. + +## Create First Site + +After starting containers, create your first site. Refer to [site operations](../04-operations/01-site-operations.md#setup-new-site) for detailed instructions. + +## Updating Images + +To update to newer versions of Frappe or ERPNext: + +```sh +# 1. Update environment variables in .env +nano .env +# Edit ERPNEXT_VERSION and FRAPPE_VERSION as needed + +# 2. Regenerate compose file with new versions +docker compose --env-file .env \ + -f compose.yaml \ + # ... your other overrides + config > ~/gitops/docker-compose.yml + +# 3. Pull new images +docker compose --project-name -f ~/gitops/docker-compose.yml pull + +# 4. Stop containers +docker compose --project-name -f ~/gitops/docker-compose.yml down + +# 5. Restart containers +docker compose --project-name -f ~/gitops/docker-compose.yml up -d +``` + +> **Note:** +> +> - Pull and stop container commands can be skipped if immutable image tags are used +> - `docker compose up -d` will pull new immutable tags if not found + +To migrate sites after updating, refer to [site operations](../04-operations/01-site-operations.md#migrate-site). + +--- + +**Back:** [Start Setup β†’](03-start-setup.md) + +**Next:** [Single Server Example β†’](07-single-server-example.md) diff --git a/docs/single-server-example.md b/docs/02-setup/07-single-server-example.md similarity index 97% rename from docs/single-server-example.md rename to docs/02-setup/07-single-server-example.md index 0bb83798..d4a459c9 100644 --- a/docs/single-server-example.md +++ b/docs/02-setup/07-single-server-example.md @@ -1,4 +1,6 @@ -### Single Server Example +# Single Server Example + +This guide demonstrates setting up multiple Frappe/ERPNext benches (projects) on a single server with shared infrastructure components. In this use case we have a single server with a static IP attached to it. It can be used in scenarios where one powerful VM has multiple benches and applications or one entry level VM with single site. For single bench, single site setup follow only up to the point where first bench and first site is added. If you choose this setup you can only scale vertically. If you need to scale horizontally you'll need to backup the sites and restore them on to cluster setup. @@ -285,4 +287,8 @@ docker compose --project-name custom-one-example -f ~/gitops/custom-one-example. ### Site operations -Refer: [site operations](./site-operations.md) +Refer: [site operations](../04-operations/01-site-operations.md) + +--- + +**Back:** [Setup Examples β†’](06-setup-examples.md) diff --git a/docs/tls-for-local-deployment.md b/docs/03-production/01-tls-ssl-setup.md similarity index 100% rename from docs/tls-for-local-deployment.md rename to docs/03-production/01-tls-ssl-setup.md diff --git a/docs/backup-and-push-cronjob.md b/docs/03-production/02-backup-strategy.md similarity index 100% rename from docs/backup-and-push-cronjob.md rename to docs/03-production/02-backup-strategy.md diff --git a/docs/port-based-multi-tenancy.md b/docs/03-production/03-multi-tenancy.md similarity index 100% rename from docs/port-based-multi-tenancy.md rename to docs/03-production/03-multi-tenancy.md diff --git a/docs/site-operations.md b/docs/04-operations/01-site-operations.md similarity index 95% rename from docs/site-operations.md rename to docs/04-operations/01-site-operations.md index 550d9bdf..1520d6aa 100644 --- a/docs/site-operations.md +++ b/docs/04-operations/01-site-operations.md @@ -15,7 +15,7 @@ docker-compose exec backend bench new-site --mariadb-user-host-login-scope=% --d If you need to install some app, specify `--install-app`. To see all options, just run `bench new-site --help`. -To create Postgres site (assuming you already use [Postgres compose override](images-and-compose-files.md#overrides)) you need have to do set `root_login` and `root_password` in common config before that: +To create Postgres site (assuming you already use [Postgres compose override](../02-setup/05-overrides.md)) you need have to do set `root_login` and `root_password` in common config before that: ```sh docker-compose exec backend bench set-config -g root_login diff --git a/docs/development.md b/docs/05-development/01-development.md similarity index 99% rename from docs/development.md rename to docs/05-development/01-development.md index 8bdeb4f8..6ff718e9 100644 --- a/docs/development.md +++ b/docs/05-development/01-development.md @@ -14,9 +14,9 @@ It is recommended you allocate at least 4GB of RAM to docker: - [Instructions for macOS](https://docs.docker.com/desktop/settings/mac/#advanced) Here is a screenshot showing the relevant setting in the Help Manual -![image](images/Docker%20Manual%20Screenshot%20-%20Resources%20section.png) +![image](../images/Docker%20Manual%20Screenshot%20-%20Resources%20section.png) Here is a screenshot showing the settings in Docker Desktop on Mac -![images](images/Docker%20Desktop%20Screenshot%20-%20Resources%20section.png) +![images](../images/Docker%20Desktop%20Screenshot%20-%20Resources%20section.png) ## Bootstrap Containers for development diff --git a/docs/bench-console-and-vscode-debugger.md b/docs/05-development/02-debugging.md similarity index 100% rename from docs/bench-console-and-vscode-debugger.md rename to docs/05-development/02-debugging.md diff --git a/docs/connect-to-localhost-services-from-containers-for-local-app-development.md b/docs/05-development/03-local-services-connection.md similarity index 100% rename from docs/connect-to-localhost-services-from-containers-for-local-app-development.md rename to docs/05-development/03-local-services-connection.md diff --git a/docs/migrate-from-multi-image-setup.md b/docs/06-migration/01-migrate-from-multi-image-setup.md similarity index 98% rename from docs/migrate-from-multi-image-setup.md rename to docs/06-migration/01-migrate-from-multi-image-setup.md index 0e3c640c..77202e0f 100644 --- a/docs/migrate-from-multi-image-setup.md +++ b/docs/06-migration/01-migrate-from-multi-image-setup.md @@ -6,7 +6,7 @@ Now you need to specify command and environment variables for following containe ### Frontend -For `frontend` service to act as static assets frontend and reverse proxy, you need to pass `nginx-entrypoint.sh` as container `command` and `BACKEND` and `SOCKETIO` environment variables pointing `{host}:{port}` for gunicorn and websocket services. Check [environment variables](environment-variables.md) +For `frontend` service to act as static assets frontend and reverse proxy, you need to pass `nginx-entrypoint.sh` as container `command` and `BACKEND` and `SOCKETIO` environment variables pointing `{host}:{port}` for gunicorn and websocket services. Check [environment variables](../02-setup/04-env-variables.md) Now you only need to mount the `sites` volume at location `/home/frappe/frappe-bench/sites`. No need for `assets` volume and asset population script or steps. diff --git a/docs/troubleshoot.md b/docs/07-troubleshooting/01-troubleshoot.md similarity index 100% rename from docs/troubleshoot.md rename to docs/07-troubleshooting/01-troubleshoot.md diff --git a/docs/error-nginx-entrypoint-windows.md b/docs/07-troubleshooting/02-windows-nginx-entrypoint-error.md similarity index 100% rename from docs/error-nginx-entrypoint-windows.md rename to docs/07-troubleshooting/02-windows-nginx-entrypoint-error.md diff --git a/docs/build-version-10-images.md b/docs/08-reference/01-build-version-10-images.md similarity index 100% rename from docs/build-version-10-images.md rename to docs/08-reference/01-build-version-10-images.md diff --git a/docs/setup-options.md b/docs/setup-options.md deleted file mode 100644 index 1d49ceea..00000000 --- a/docs/setup-options.md +++ /dev/null @@ -1,131 +0,0 @@ -# Containerized Production Setup - -Make sure you've cloned this repository and switch to the directory before executing following commands. - -Commands will generate YAML as per the environment for setup. - -## Prerequisites - -- [docker](https://docker.com/get-started) -- [docker compose v2](https://docs.docker.com/compose/cli-command) - -## Setup Environment Variables - -Copy the example docker environment file to `.env`: - -```sh -cp example.env .env -``` - -Note: To know more about environment variable [read here](./environment-variables.md). Set the necessary variables in the `.env` file. - -## Generate docker-compose.yml for variety of setups - -Notes: - -- Make sure to replace `` with the desired name you wish to set for the project. -- This setup is not to be used for development. A complete development environment is available [here](../development) - -### Store the yaml files - -YAML files generated by `docker compose config` command can be stored in a directory. We will create a directory called `gitops` in the user's home. - -```shell -mkdir ~/gitops -``` - -You can make the directory into a private git repo which stores the yaml and secrets. It can help in tracking changes. - -Instead of `docker compose config`, you can directly use `docker compose up` to start the containers and skip storing the yamls in `gitops` directory. - -### Setup Frappe without proxy and external MariaDB and Redis - -In this case make sure you've set `DB_HOST`, `DB_PORT`, `REDIS_CACHE` and `REDIS_QUEUE` environment variables or the `configurator` will fail. - -```sh -# Generate YAML -docker compose -f compose.yaml -f overrides/compose.noproxy.yaml config > ~/gitops/docker-compose.yml - -# Start containers -docker compose --project-name -f ~/gitops/docker-compose.yml up -d -``` - -### Setup ERPNext with proxy and external MariaDB and Redis - -In this case make sure you've set `DB_HOST`, `DB_PORT`, `REDIS_CACHE` and `REDIS_QUEUE` environment variables or the `configurator` will fail. - -```sh -# Generate YAML -docker compose -f compose.yaml \ - -f overrides/compose.proxy.yaml \ - config > ~/gitops/docker-compose.yml - -# Start containers -docker compose --project-name -f ~/gitops/docker-compose.yml up -d -``` - -### Setup Frappe using containerized MariaDB and Redis with Letsencrypt certificates. - -In this case make sure you've set `LETSENCRYPT_EMAIL` and `SITES` environment variables are set or certificates won't work. - -```sh -# Generate YAML -docker compose -f compose.yaml \ - -f overrides/compose.mariadb.yaml \ - -f overrides/compose.redis.yaml \ - -f overrides/compose.https.yaml \ - config > ~/gitops/docker-compose.yml - -# Start containers -docker compose --project-name -f ~/gitops/docker-compose.yml up -d -``` - -### Setup ERPNext using containerized MariaDB and Redis with Letsencrypt certificates. - -In this case make sure you've set `LETSENCRYPT_EMAIL` and `SITES` environment variables are set or certificates won't work. - -```sh -# Generate YAML -docker compose -f compose.yaml \ - -f overrides/compose.mariadb.yaml \ - -f overrides/compose.redis.yaml \ - -f overrides/compose.https.yaml \ - config > ~/gitops/docker-compose.yml - -# Start containers -docker compose --project-name -f ~/gitops/docker-compose.yml up -d -``` - -## Create first site - -After starting containers, the first site needs to be created. Refer [site operations](./site-operations.md#setup-new-site). - -## Updating Images - -Switch to the root of the `frappe_docker` directory before running the following commands: - -```sh -# Update environment variables ERPNEXT_VERSION and FRAPPE_VERSION -nano .env - -# Pull new images -docker compose -f compose.yaml \ - # ... your other overrides - config > ~/gitops/docker-compose.yml - -# Pull images -docker compose --project-name -f ~/gitops/docker-compose.yml pull - -# Stop containers -docker compose --project-name -f ~/gitops/docker-compose.yml down - -# Restart containers -docker compose --project-name -f ~/gitops/docker-compose.yml up -d -``` - -Note: - -- pull and stop container commands can be skipped if immutable image tags are used -- `docker compose up -d` will pull new immutable tags if not found. - -To migrate sites refer [site operations](./site-operations.md#migrate-site) From 47c6a21482a812d5502ad0beca679c699e807aa5 Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 9 Dec 2025 17:34:54 +0000 Subject: [PATCH 064/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 3aeb05d2..02c62703 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v15.91.0 +ERPNEXT_VERSION=v15.91.1 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index f00f973d..8f28e28d 100644 --- a/pwd.yml +++ b/pwd.yml @@ -2,7 +2,7 @@ version: "3" services: backend: - image: frappe/erpnext:v15.91.0 + image: frappe/erpnext:v15.91.1 networks: - frappe_network deploy: @@ -18,7 +18,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v15.91.0 + image: frappe/erpnext:v15.91.1 networks: - frappe_network deploy: @@ -47,7 +47,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v15.91.0 + image: frappe/erpnext:v15.91.1 networks: - frappe_network deploy: @@ -102,7 +102,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v15.91.0 + image: frappe/erpnext:v15.91.1 networks: - frappe_network depends_on: @@ -128,7 +128,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v15.91.0 + image: frappe/erpnext:v15.91.1 networks: - frappe_network deploy: @@ -147,7 +147,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v15.91.0 + image: frappe/erpnext:v15.91.1 networks: - frappe_network deploy: @@ -184,7 +184,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v15.91.0 + image: frappe/erpnext:v15.91.1 networks: - frappe_network deploy: @@ -198,7 +198,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v15.91.0 + image: frappe/erpnext:v15.91.1 networks: - frappe_network deploy: From 4548ead3dd47df24c20d1304aeeea6261b4d70ee Mon Sep 17 00:00:00 2001 From: Michael Uray Date: Tue, 9 Dec 2025 23:28:00 +0100 Subject: [PATCH 065/279] Update link to site operations documentation Fixed link to 04-operations/01-site-operations.md --- docs/02-setup/03-start-setup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/02-setup/03-start-setup.md b/docs/02-setup/03-start-setup.md index 53dba44c..bbcb1258 100644 --- a/docs/02-setup/03-start-setup.md +++ b/docs/02-setup/03-start-setup.md @@ -45,7 +45,7 @@ docker compose -p frappe exec backend bench new-site \ > **Note:** Wait for the `db` service to start and `configurator` to exit before trying to create a new site. Usually this takes up to 10 seconds. -For more site operations, refer to [site operations](../../04-operations/01-site-operations.md). +For more site operations, refer to [site operations](../04-operations/01-site-operations.md). > ## Understanding the MariaDB User Scope > From 43ea59db62a67745a622359bf810731152584fcc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 11 Dec 2025 06:09:36 +0530 Subject: [PATCH 066/279] chore(deps): bump pytest from 9.0.1 to 9.0.2 (#1761) Bumps [pytest](https://github.com/pytest-dev/pytest) from 9.0.1 to 9.0.2. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/9.0.1...9.0.2) --- updated-dependencies: - dependency-name: pytest dependency-version: 9.0.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements-test.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-test.txt b/requirements-test.txt index 02559c42..5b240e09 100644 --- a/requirements-test.txt +++ b/requirements-test.txt @@ -1 +1 @@ -pytest==9.0.1 +pytest==9.0.2 From ac01dd86f142f406e17d40aaa15c943aacf2eae3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 11 Dec 2025 06:10:54 +0530 Subject: [PATCH 067/279] chore(deps): bump peter-evans/create-pull-request from 7 to 8 (#1765) Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 7 to 8. - [Release notes](https://github.com/peter-evans/create-pull-request/releases) - [Commits](https://github.com/peter-evans/create-pull-request/compare/v7...v8) --- updated-dependencies: - dependency-name: peter-evans/create-pull-request dependency-version: '8' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/pre-commit-autoupdate.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pre-commit-autoupdate.yml b/.github/workflows/pre-commit-autoupdate.yml index a8ef378d..9b7dc125 100644 --- a/.github/workflows/pre-commit-autoupdate.yml +++ b/.github/workflows/pre-commit-autoupdate.yml @@ -16,7 +16,7 @@ jobs: uses: vrslev/pre-commit-autoupdate@v1.0.0 - name: Create Pull Request - uses: peter-evans/create-pull-request@v7 + uses: peter-evans/create-pull-request@v8 with: branch: pre-commit-autoupdate title: "chore(deps): Update pre-commit hooks" From 979d54eeb68490d6f62f8d9cccbaa10648326dec Mon Sep 17 00:00:00 2001 From: github-actions Date: Thu, 11 Dec 2025 11:23:56 +0000 Subject: [PATCH 068/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 02c62703..93752000 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v15.91.1 +ERPNEXT_VERSION=v15.91.2 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index 8f28e28d..f331b6a9 100644 --- a/pwd.yml +++ b/pwd.yml @@ -2,7 +2,7 @@ version: "3" services: backend: - image: frappe/erpnext:v15.91.1 + image: frappe/erpnext:v15.91.2 networks: - frappe_network deploy: @@ -18,7 +18,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v15.91.1 + image: frappe/erpnext:v15.91.2 networks: - frappe_network deploy: @@ -47,7 +47,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v15.91.1 + image: frappe/erpnext:v15.91.2 networks: - frappe_network deploy: @@ -102,7 +102,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v15.91.1 + image: frappe/erpnext:v15.91.2 networks: - frappe_network depends_on: @@ -128,7 +128,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v15.91.1 + image: frappe/erpnext:v15.91.2 networks: - frappe_network deploy: @@ -147,7 +147,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v15.91.1 + image: frappe/erpnext:v15.91.2 networks: - frappe_network deploy: @@ -184,7 +184,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v15.91.1 + image: frappe/erpnext:v15.91.2 networks: - frappe_network deploy: @@ -198,7 +198,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v15.91.1 + image: frappe/erpnext:v15.91.2 networks: - frappe_network deploy: From b647e0c8392d8fcfbdae5d27822ee714ce6e395a Mon Sep 17 00:00:00 2001 From: github-actions Date: Fri, 12 Dec 2025 09:32:45 +0000 Subject: [PATCH 069/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 93752000..bbcdf9d9 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v15.91.2 +ERPNEXT_VERSION=v15.91.3 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index f331b6a9..c0cc8fba 100644 --- a/pwd.yml +++ b/pwd.yml @@ -2,7 +2,7 @@ version: "3" services: backend: - image: frappe/erpnext:v15.91.2 + image: frappe/erpnext:v15.91.3 networks: - frappe_network deploy: @@ -18,7 +18,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v15.91.2 + image: frappe/erpnext:v15.91.3 networks: - frappe_network deploy: @@ -47,7 +47,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v15.91.2 + image: frappe/erpnext:v15.91.3 networks: - frappe_network deploy: @@ -102,7 +102,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v15.91.2 + image: frappe/erpnext:v15.91.3 networks: - frappe_network depends_on: @@ -128,7 +128,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v15.91.2 + image: frappe/erpnext:v15.91.3 networks: - frappe_network deploy: @@ -147,7 +147,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v15.91.2 + image: frappe/erpnext:v15.91.3 networks: - frappe_network deploy: @@ -184,7 +184,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v15.91.2 + image: frappe/erpnext:v15.91.3 networks: - frappe_network deploy: @@ -198,7 +198,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v15.91.2 + image: frappe/erpnext:v15.91.3 networks: - frappe_network deploy: From fe16bf9c00899427861c368bf6efc2e1333680bf Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 16 Dec 2025 15:47:23 +0000 Subject: [PATCH 070/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index bbcdf9d9..a179c61a 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v15.91.3 +ERPNEXT_VERSION=v15.92.0 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index c0cc8fba..c484d6af 100644 --- a/pwd.yml +++ b/pwd.yml @@ -2,7 +2,7 @@ version: "3" services: backend: - image: frappe/erpnext:v15.91.3 + image: frappe/erpnext:v15.92.0 networks: - frappe_network deploy: @@ -18,7 +18,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v15.91.3 + image: frappe/erpnext:v15.92.0 networks: - frappe_network deploy: @@ -47,7 +47,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v15.91.3 + image: frappe/erpnext:v15.92.0 networks: - frappe_network deploy: @@ -102,7 +102,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v15.91.3 + image: frappe/erpnext:v15.92.0 networks: - frappe_network depends_on: @@ -128,7 +128,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v15.91.3 + image: frappe/erpnext:v15.92.0 networks: - frappe_network deploy: @@ -147,7 +147,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v15.91.3 + image: frappe/erpnext:v15.92.0 networks: - frappe_network deploy: @@ -184,7 +184,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v15.91.3 + image: frappe/erpnext:v15.92.0 networks: - frappe_network deploy: @@ -198,7 +198,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v15.91.3 + image: frappe/erpnext:v15.92.0 networks: - frappe_network deploy: From 92a3494ded70adb52e350f8bdaca3ae7bd6cf683 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?A=CC=B4m=CC=B4r=CC=B4=20=D8=B9=CC=B2=D9=85=D9=90=DB=92?= =?UTF-8?q?=D9=80=D8=B1=DB=85?= Date: Wed, 17 Dec 2025 11:10:10 +0200 Subject: [PATCH 071/279] Remoed the `version` attribute from docker compose files --- devcontainer-example/docker-compose.yml | 1 - overrides/compose.custom-domain.yaml | 2 -- overrides/compose.mariadb-shared.yaml | 2 -- overrides/compose.traefik.yaml | 2 -- pwd.yml | 2 -- 5 files changed, 9 deletions(-) diff --git a/devcontainer-example/docker-compose.yml b/devcontainer-example/docker-compose.yml index 0d6d9d8a..3c23b4f3 100644 --- a/devcontainer-example/docker-compose.yml +++ b/devcontainer-example/docker-compose.yml @@ -1,4 +1,3 @@ -version: "3.7" services: mariadb: image: docker.io/mariadb:11.8 diff --git a/overrides/compose.custom-domain.yaml b/overrides/compose.custom-domain.yaml index 5746a325..e7c82f90 100644 --- a/overrides/compose.custom-domain.yaml +++ b/overrides/compose.custom-domain.yaml @@ -1,5 +1,3 @@ -version: "3.3" - services: custom-domain: image: caddy:2 diff --git a/overrides/compose.mariadb-shared.yaml b/overrides/compose.mariadb-shared.yaml index 30d148e3..f28031c0 100644 --- a/overrides/compose.mariadb-shared.yaml +++ b/overrides/compose.mariadb-shared.yaml @@ -1,5 +1,3 @@ -version: "3.3" - services: database: container_name: mariadb-database diff --git a/overrides/compose.traefik.yaml b/overrides/compose.traefik.yaml index 25d362af..7765e19d 100644 --- a/overrides/compose.traefik.yaml +++ b/overrides/compose.traefik.yaml @@ -1,5 +1,3 @@ -version: "3.3" - services: traefik: image: "traefik:v2.11" diff --git a/pwd.yml b/pwd.yml index c484d6af..f907ca55 100644 --- a/pwd.yml +++ b/pwd.yml @@ -1,5 +1,3 @@ -version: "3" - services: backend: image: frappe/erpnext:v15.92.0 From 69bf7a9f678327d0cf652f3adbbc647722ffa234 Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 17 Dec 2025 10:09:44 +0000 Subject: [PATCH 072/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index a179c61a..f6a9a8b9 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v15.92.0 +ERPNEXT_VERSION=v15.92.1 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index c484d6af..90ae9ae7 100644 --- a/pwd.yml +++ b/pwd.yml @@ -2,7 +2,7 @@ version: "3" services: backend: - image: frappe/erpnext:v15.92.0 + image: frappe/erpnext:v15.92.1 networks: - frappe_network deploy: @@ -18,7 +18,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v15.92.0 + image: frappe/erpnext:v15.92.1 networks: - frappe_network deploy: @@ -47,7 +47,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v15.92.0 + image: frappe/erpnext:v15.92.1 networks: - frappe_network deploy: @@ -102,7 +102,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v15.92.0 + image: frappe/erpnext:v15.92.1 networks: - frappe_network depends_on: @@ -128,7 +128,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v15.92.0 + image: frappe/erpnext:v15.92.1 networks: - frappe_network deploy: @@ -147,7 +147,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v15.92.0 + image: frappe/erpnext:v15.92.1 networks: - frappe_network deploy: @@ -184,7 +184,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v15.92.0 + image: frappe/erpnext:v15.92.1 networks: - frappe_network deploy: @@ -198,7 +198,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v15.92.0 + image: frappe/erpnext:v15.92.1 networks: - frappe_network deploy: From f00657856a2c4e04e6cd17c361ff339a407629c8 Mon Sep 17 00:00:00 2001 From: github-actions Date: Thu, 18 Dec 2025 13:12:58 +0000 Subject: [PATCH 073/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index f6a9a8b9..0471b620 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v15.92.1 +ERPNEXT_VERSION=v15.92.2 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index 303fb4cf..5c60f1a3 100644 --- a/pwd.yml +++ b/pwd.yml @@ -1,6 +1,6 @@ services: backend: - image: frappe/erpnext:v15.92.1 + image: frappe/erpnext:v15.92.2 networks: - frappe_network deploy: @@ -16,7 +16,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v15.92.1 + image: frappe/erpnext:v15.92.2 networks: - frappe_network deploy: @@ -45,7 +45,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v15.92.1 + image: frappe/erpnext:v15.92.2 networks: - frappe_network deploy: @@ -100,7 +100,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v15.92.1 + image: frappe/erpnext:v15.92.2 networks: - frappe_network depends_on: @@ -126,7 +126,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v15.92.1 + image: frappe/erpnext:v15.92.2 networks: - frappe_network deploy: @@ -145,7 +145,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v15.92.1 + image: frappe/erpnext:v15.92.2 networks: - frappe_network deploy: @@ -182,7 +182,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v15.92.1 + image: frappe/erpnext:v15.92.2 networks: - frappe_network deploy: @@ -196,7 +196,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v15.92.1 + image: frappe/erpnext:v15.92.2 networks: - frappe_network deploy: From daca8b134fdf366e232332f6b841d1e265dffa31 Mon Sep 17 00:00:00 2001 From: github-actions Date: Fri, 19 Dec 2025 14:00:01 +0000 Subject: [PATCH 074/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 0471b620..3231a7f8 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v15.92.2 +ERPNEXT_VERSION=v15.92.3 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index 5c60f1a3..4b6fd28a 100644 --- a/pwd.yml +++ b/pwd.yml @@ -1,6 +1,6 @@ services: backend: - image: frappe/erpnext:v15.92.2 + image: frappe/erpnext:v15.92.3 networks: - frappe_network deploy: @@ -16,7 +16,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v15.92.2 + image: frappe/erpnext:v15.92.3 networks: - frappe_network deploy: @@ -45,7 +45,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v15.92.2 + image: frappe/erpnext:v15.92.3 networks: - frappe_network deploy: @@ -100,7 +100,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v15.92.2 + image: frappe/erpnext:v15.92.3 networks: - frappe_network depends_on: @@ -126,7 +126,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v15.92.2 + image: frappe/erpnext:v15.92.3 networks: - frappe_network deploy: @@ -145,7 +145,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v15.92.2 + image: frappe/erpnext:v15.92.3 networks: - frappe_network deploy: @@ -182,7 +182,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v15.92.2 + image: frappe/erpnext:v15.92.3 networks: - frappe_network deploy: @@ -196,7 +196,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v15.92.2 + image: frappe/erpnext:v15.92.3 networks: - frappe_network deploy: From d53666742f844624d55cbc0ae7e789334af14b06 Mon Sep 17 00:00:00 2001 From: github-actions Date: Mon, 22 Dec 2025 09:11:26 +0000 Subject: [PATCH 075/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 3231a7f8..dbd351cc 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v15.92.3 +ERPNEXT_VERSION=v15.92.4 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index 4b6fd28a..fbde5bfc 100644 --- a/pwd.yml +++ b/pwd.yml @@ -1,6 +1,6 @@ services: backend: - image: frappe/erpnext:v15.92.3 + image: frappe/erpnext:v15.92.4 networks: - frappe_network deploy: @@ -16,7 +16,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v15.92.3 + image: frappe/erpnext:v15.92.4 networks: - frappe_network deploy: @@ -45,7 +45,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v15.92.3 + image: frappe/erpnext:v15.92.4 networks: - frappe_network deploy: @@ -100,7 +100,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v15.92.3 + image: frappe/erpnext:v15.92.4 networks: - frappe_network depends_on: @@ -126,7 +126,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v15.92.3 + image: frappe/erpnext:v15.92.4 networks: - frappe_network deploy: @@ -145,7 +145,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v15.92.3 + image: frappe/erpnext:v15.92.4 networks: - frappe_network deploy: @@ -182,7 +182,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v15.92.3 + image: frappe/erpnext:v15.92.4 networks: - frappe_network deploy: @@ -196,7 +196,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v15.92.3 + image: frappe/erpnext:v15.92.4 networks: - frappe_network deploy: From 43863d2537ed05549cceeab166ec695dd578b37b Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 23 Dec 2025 08:54:33 +0000 Subject: [PATCH 076/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index dbd351cc..de00a638 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v15.92.4 +ERPNEXT_VERSION=v15.92.5 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index fbde5bfc..784f2cf3 100644 --- a/pwd.yml +++ b/pwd.yml @@ -1,6 +1,6 @@ services: backend: - image: frappe/erpnext:v15.92.4 + image: frappe/erpnext:v15.92.5 networks: - frappe_network deploy: @@ -16,7 +16,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v15.92.4 + image: frappe/erpnext:v15.92.5 networks: - frappe_network deploy: @@ -45,7 +45,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v15.92.4 + image: frappe/erpnext:v15.92.5 networks: - frappe_network deploy: @@ -100,7 +100,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v15.92.4 + image: frappe/erpnext:v15.92.5 networks: - frappe_network depends_on: @@ -126,7 +126,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v15.92.4 + image: frappe/erpnext:v15.92.5 networks: - frappe_network deploy: @@ -145,7 +145,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v15.92.4 + image: frappe/erpnext:v15.92.5 networks: - frappe_network deploy: @@ -182,7 +182,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v15.92.4 + image: frappe/erpnext:v15.92.5 networks: - frappe_network deploy: @@ -196,7 +196,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v15.92.4 + image: frappe/erpnext:v15.92.5 networks: - frappe_network deploy: From a1bbe96594e792a3d439de7c03efbff173696cb0 Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 23 Dec 2025 17:07:48 +0000 Subject: [PATCH 077/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index de00a638..ae9c98d0 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v15.92.5 +ERPNEXT_VERSION=v15.93.0 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index 784f2cf3..c9b6a38d 100644 --- a/pwd.yml +++ b/pwd.yml @@ -1,6 +1,6 @@ services: backend: - image: frappe/erpnext:v15.92.5 + image: frappe/erpnext:v15.93.0 networks: - frappe_network deploy: @@ -16,7 +16,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v15.92.5 + image: frappe/erpnext:v15.93.0 networks: - frappe_network deploy: @@ -45,7 +45,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v15.92.5 + image: frappe/erpnext:v15.93.0 networks: - frappe_network deploy: @@ -100,7 +100,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v15.92.5 + image: frappe/erpnext:v15.93.0 networks: - frappe_network depends_on: @@ -126,7 +126,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v15.92.5 + image: frappe/erpnext:v15.93.0 networks: - frappe_network deploy: @@ -145,7 +145,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v15.92.5 + image: frappe/erpnext:v15.93.0 networks: - frappe_network deploy: @@ -182,7 +182,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v15.92.5 + image: frappe/erpnext:v15.93.0 networks: - frappe_network deploy: @@ -196,7 +196,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v15.92.5 + image: frappe/erpnext:v15.93.0 networks: - frappe_network deploy: From 9317c953337d3f5bf17f0be714ca8b870efbfa3f Mon Sep 17 00:00:00 2001 From: Akhil Narang Date: Wed, 24 Dec 2025 16:07:05 +0530 Subject: [PATCH 078/279] fix: use python 3.14 and node 24 for v16/develop Signed-off-by: Akhil Narang --- .github/workflows/build_develop.yml | 4 ++-- .github/workflows/build_stable.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build_develop.yml b/.github/workflows/build_develop.yml index 6103fd5f..8ec061ed 100644 --- a/.github/workflows/build_develop.yml +++ b/.github/workflows/build_develop.yml @@ -26,8 +26,8 @@ jobs: repo: erpnext version: develop push: ${{ github.repository == 'frappe/frappe_docker' && github.event_name != 'pull_request' }} - python_version: 3.11.6 - node_version: 20.19.2 + python_version: 3.14.2 + node_version: 24.12.0 secrets: DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }} DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} diff --git a/.github/workflows/build_stable.yml b/.github/workflows/build_stable.yml index 01c0eed6..0f1b8cfb 100644 --- a/.github/workflows/build_stable.yml +++ b/.github/workflows/build_stable.yml @@ -60,8 +60,8 @@ jobs: repo: erpnext version: "16" push: ${{ github.repository == 'frappe/frappe_docker' && github.event_name != 'pull_request' }} - python_version: 3.12.12 - node_version: 22.21.1 + python_version: 3.14.2 + node_version: 24.12.0 secrets: DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }} DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} From e30f03ccbada6635f6af9a91067f739b9bb320bb Mon Sep 17 00:00:00 2001 From: Akhil Narang Date: Wed, 24 Dec 2025 18:23:52 +0530 Subject: [PATCH 079/279] fix: use python 3.14 and node 24 for bench image Signed-off-by: Akhil Narang --- images/bench/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/images/bench/Dockerfile b/images/bench/Dockerfile index 181a6623..59b3360c 100644 --- a/images/bench/Dockerfile +++ b/images/bench/Dockerfile @@ -100,7 +100,7 @@ WORKDIR /home/frappe # Install Python via pyenv ENV PYTHON_VERSION_V14=3.10.13 -ENV PYTHON_VERSION=3.11.6 +ENV PYTHON_VERSION=3.14.2 ENV PYENV_ROOT=/home/frappe/.pyenv ENV PATH=$PYENV_ROOT/shims:$PYENV_ROOT/bin:$PATH @@ -127,7 +127,7 @@ RUN git clone ${GIT_REPO} --depth 1 -b ${GIT_BRANCH} .bench \ # Install Node via nvm ENV NODE_VERSION_14=16.20.2 -ENV NODE_VERSION=20.19.2 +ENV NODE_VERSION=24.12.0 ENV NVM_DIR=/home/frappe/.nvm ENV PATH=${NVM_DIR}/versions/node/v${NODE_VERSION}/bin/:${PATH} From 7de99474cb61a3513ebd6aa3dffd06b25e27c504 Mon Sep 17 00:00:00 2001 From: Daniel Radl Date: Thu, 25 Dec 2025 00:50:35 +0100 Subject: [PATCH 080/279] docs: added deployment methode chooser (#1777) --- .../01-choosing-a-deployment-method.md | 122 ++++++++++++++++++ .../02-docker-immutability.md | 48 +++++++ ...nux-mac.md => 03-quick-start-linux-mac.md} | 0 ...se-setup.md => 04-single-compose-setup.md} | 0 docs/getting-started.md | 4 + 5 files changed, 174 insertions(+) create mode 100644 docs/01-getting-started/01-choosing-a-deployment-method.md create mode 100644 docs/01-getting-started/02-docker-immutability.md rename docs/01-getting-started/{01-quick-start-linux-mac.md => 03-quick-start-linux-mac.md} (100%) rename docs/01-getting-started/{02-single-compose-setup.md => 04-single-compose-setup.md} (100%) diff --git a/docs/01-getting-started/01-choosing-a-deployment-method.md b/docs/01-getting-started/01-choosing-a-deployment-method.md new file mode 100644 index 00000000..11b39a8f --- /dev/null +++ b/docs/01-getting-started/01-choosing-a-deployment-method.md @@ -0,0 +1,122 @@ +# Choosing a Deployment or Development Method + +This repository (`frappe_docker`) supports **multiple ways to run Frappe using Docker**. +Each method is designed for a **specific purpose**, and they are **not interchangeable**. + +This document explains: + +- All supported ways to use this repository +- Which method to choose depending on your goal +- Common misconceptions, especially around persistence and app installation + +Reading this document **before following any setup guide** is strongly recommended. + +## Overview + +| Goal | Recommended Method | Production Ready | +| ---------------------------- | ------------------------- | ---------------- | +| Quick exploration | `pwd.yml` | ❌ | +| Local development | VS Code Devcontainers | ❌ | +| Automated production install | Easy Install Script | βœ… | +| Manual production deployment | `compose.yml` + overrides | βœ… | + +## 1. `pwd.yml` – Quick Test / Exploration Setup + +The `pwd.yml` file is a **single, self-contained Docker Compose file** intended for: + +- Trying out Frappe and ERPNext +- Demos and short-lived test environments +- Learning the basics without setup overhead + +### Characteristics + +- One Compose file +- Minimal configuration +- Fast startup +- Disposable by design + +### Limitations + +- ❌ **Not intended for production** +- ❌ **Not intended for development** +- ❌ **Not suitable as a migration starting point** + +If you start with `pwd.yml`, you should expect to **throw the environment away**. + +## 2. VS Code Devcontainers – Local Development Setup + +The development setup described in [`/docs/05-development`](../05-development) + +uses **VS Code Devcontainers** to provide a **local Frappe development environment**. + +### Intended Use + +- Developing Frappe or custom apps +- Working with source code +- Debugging and testing changes locally + +### Key Differences from Other Setups + +- Optimized for **interactive development** +- Code is editable live +- Containers are tailored for developer workflows +- Not designed to represent a production environment + +### Important Notes + +- ❌ **Not a deployment method** +- ❌ **Not intended for production** +- βœ” The **correct way** to do local development with this repository + +Using production-oriented setups (`pwd.yml` or `compose.yml`) for development is strongly discouraged. + +## 3. Easy Install Script (from `frappe/bench`) + +The Easy Install script provided in the [`frappe/bench`](https://github.com/frappe/bench) repository uses `frappe_docker` internally and automates a full deployment process. + +It is comparable to what a **deployment pipeline** would perform. + +### What It Does + +- Installs Docker and prerequisites +- Pulls and configures `frappe_docker` +- Uses production-grade images and services +- Reduces manual configuration + +### Intended Use + +- Production environments +- Users who want a guided, automated installation +- Server deployments with minimal manual steps + +### Production Readiness + +βœ” **Yes** β€” suitable for real production systems +βœ” Uses the same components as the manual production setup + +## 4. `compose.yml` + Overrides – Intended Production Setup + +This is the **canonical production deployment method** for `frappe_docker`. + +It uses: + +- The main `compose.yml` +- Override files from the `overrides/` directory + +Detailed instructions are available in [`/docs/02-setup`](../02-setup) + +### Characteristics + +- Explicit service definitions +- Flexible and configurable +- Designed for long-running production environments +- Suitable for advanced and customized deployments + +**This is the preferred approach for teams managing their own infrastructure.** + +## Summary + +- Each setup serves a **distinct purpose** +- Development, testing, and production are **separate workflows** +- Do not expect to evolve a disposable setup into production +- Apps must be included **at build time**, not installed later ([Docker immutability](02-docker-immutability.md)) diff --git a/docs/01-getting-started/02-docker-immutability.md b/docs/01-getting-started/02-docker-immutability.md new file mode 100644 index 00000000..38a82330 --- /dev/null +++ b/docs/01-getting-started/02-docker-immutability.md @@ -0,0 +1,48 @@ +# Important Concept: Immutability and Persistence + +A frequent source of confusion is how **Docker-based Frappe deployments handle persistence**. + +### Containers Are Immutable + +Docker containers are **not meant to be modified after they are built**. +You should only change: + +- Environment variables +- Mounted volumes +- The Docker image itself (via rebuild) + +### What Is Persistent + +Typically, only these paths are persisted: + +- Site data (`/sites`) +- Database storage + +This allows you to: + +- Create new sites +- Run migrations +- Perform backups and restores +- Recreate containers safely + +## Installing Apps After Deployment + +### ❌ Not Supported + +Installing apps into a running container is **not supported**. + +`bench get-app` is an examples of an common but unsupported action. + +### Why? + +- Apps are part of the **Docker image** +- Runtime changes are lost on container recreation +- This ensures reproducibility and stability + +### Correct Workflow + +1. Add the app to the image build configuration +2. Rebuild the Docker image +3. Redeploy the stack + +This applies to **all production-oriented setups**. diff --git a/docs/01-getting-started/01-quick-start-linux-mac.md b/docs/01-getting-started/03-quick-start-linux-mac.md similarity index 100% rename from docs/01-getting-started/01-quick-start-linux-mac.md rename to docs/01-getting-started/03-quick-start-linux-mac.md diff --git a/docs/01-getting-started/02-single-compose-setup.md b/docs/01-getting-started/04-single-compose-setup.md similarity index 100% rename from docs/01-getting-started/02-single-compose-setup.md rename to docs/01-getting-started/04-single-compose-setup.md diff --git a/docs/getting-started.md b/docs/getting-started.md index ea615c37..f87b8617 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -66,6 +66,10 @@ Real-time: ### πŸ“ Core Configuration Files +> ⚠️ Before deploying, read +> **[Choosing a Deployment Method](01-getting-started/01-choosing-a-deployment-method.md)** +> to understand the differences between `pwd.yml`, development setup, the Easy Install script and the production setup. + - **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 From a6eba1e913d5110fc9a3fd7ee90fa4dba2a74c7d Mon Sep 17 00:00:00 2001 From: "daniel.radl" Date: Mon, 29 Dec 2025 10:42:25 +0100 Subject: [PATCH 081/279] docs: use costom.env in setup --- docs/02-setup/02-build-setup.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/docs/02-setup/02-build-setup.md b/docs/02-setup/02-build-setup.md index ace05f49..6c0c49da 100644 --- a/docs/02-setup/02-build-setup.md +++ b/docs/02-setup/02-build-setup.md @@ -97,12 +97,26 @@ cp example.env custom.env Edit `custom.env` to customize variables for your setup. The template includes common variables, but you can add, modify, or remove any as needed. See [env-variables.md](04-env-variables.md) for detailed descriptions of all available variables. +For this setup, make sure **at least** the following values are added to `custom.env`: + +```txt +CUSTOM_IMAGE=custom +CUSTOM_TAG=15 +PULL_POLICY=missing +``` + +> The `CUSTOM_*` variables ensure the image reference points to the recently built image. +> `PULL_POLICY` ensures Docker does not attempt to pull the image, but instead uses the locally built one (the default pull policy is `always`). + +**⚠️ This is not meant to be a complete `.env` configuration guide. These are only the minimal additions required for this example. +Please have a look at [env-variables.md](04-env-variables.md) for a full description of all available variables and adjust them according to your needs.** + # Creating the final compose file Combine the base compose file with appropriate overrides for your use case. This example adds MariaDB, Redis, and exposes ports on `:8080`: ```bash -docker compose --env-file example.env \ +docker compose --env-file custom.env \ -f compose.yaml \ -f overrides/compose.mariadb.yaml \ -f overrides/compose.redis.yaml \ From afcc450311f47bfbd2755ae29f954ebecb8ae326 Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 30 Dec 2025 13:58:32 +0000 Subject: [PATCH 082/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index ae9c98d0..162f1bc9 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v15.93.0 +ERPNEXT_VERSION=v15.93.1 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index c9b6a38d..fb999e5c 100644 --- a/pwd.yml +++ b/pwd.yml @@ -1,6 +1,6 @@ services: backend: - image: frappe/erpnext:v15.93.0 + image: frappe/erpnext:v15.93.1 networks: - frappe_network deploy: @@ -16,7 +16,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v15.93.0 + image: frappe/erpnext:v15.93.1 networks: - frappe_network deploy: @@ -45,7 +45,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v15.93.0 + image: frappe/erpnext:v15.93.1 networks: - frappe_network deploy: @@ -100,7 +100,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v15.93.0 + image: frappe/erpnext:v15.93.1 networks: - frappe_network depends_on: @@ -126,7 +126,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v15.93.0 + image: frappe/erpnext:v15.93.1 networks: - frappe_network deploy: @@ -145,7 +145,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v15.93.0 + image: frappe/erpnext:v15.93.1 networks: - frappe_network deploy: @@ -182,7 +182,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v15.93.0 + image: frappe/erpnext:v15.93.1 networks: - frappe_network deploy: @@ -196,7 +196,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v15.93.0 + image: frappe/erpnext:v15.93.1 networks: - frappe_network deploy: From 4b90bfdade8618c542594ff8247d1a7cc2b46d83 Mon Sep 17 00:00:00 2001 From: Daniel Radl Date: Thu, 1 Jan 2026 22:00:45 +0100 Subject: [PATCH 083/279] docs(readme): refactor readme to explaining how to navigate this repository (#1779) --- CONTRIBUTING.md | 39 +++++ README.md | 136 +++++++++--------- ...3-quick-start-linux-mac.md => 03-arm64.md} | 32 +++-- 3 files changed, 126 insertions(+), 81 deletions(-) rename docs/01-getting-started/{03-quick-start-linux-mac.md => 03-arm64.md} (92%) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3cc671ee..3389cfe0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -6,6 +6,45 @@ On each PR that contains changes relevant to Docker builds, images are being bui > :evergreen_tree: Please be considerate when pushing commits and opening PR for multiple branches, as the process of building images uses energy and contributes to global warming. +## Pull Request Process + +1. Test builds locally before submitting +2. Follow conventional commit format +3. Update documentation if needed +4. Ensure all pre-commit checks pass +5. Reference related issues in PR description + +## Commit Message Convention + +We recommend [Conventional Commits](https://www.conventionalcommits.org/) for clear and semantic commit history. + +Format: `(): ` + +**Types:** + +- `feat`: New feature +- `fix`: Bug fix +- `docs`: Documentation changes +- `style`: Code style changes (formatting, missing semicolons, etc.) +- `refactor`: Code refactoring +- `test`: Adding or updating tests +- `chore`: Maintenance tasks (dependencies, build config, etc.) +- `ci`: CI/CD changes + +**Examples:** + +``` +chore(deps): bump wkhtmltopdf version +fix(ci): correct buildx cache configuration +docs(contributing): add conventional commits guidelines +``` + +## Branch Naming + +- `feature/` - New features +- `fix/` - Bug fixes +- `docs/` - Documentation updates + ## Lint We use `pre-commit` framework to lint the codebase before committing. diff --git a/README.md b/README.md index 1296dd5d..6619e4d2 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,66 @@ +# Frappe Docker + [![Build Stable](https://github.com/frappe/frappe_docker/actions/workflows/build_stable.yml/badge.svg)](https://github.com/frappe/frappe_docker/actions/workflows/build_stable.yml) [![Build Develop](https://github.com/frappe/frappe_docker/actions/workflows/build_develop.yml/badge.svg)](https://github.com/frappe/frappe_docker/actions/workflows/build_develop.yml) -Everything about [Frappe](https://github.com/frappe/frappe) and [ERPNext](https://github.com/frappe/erpnext) in containers. +Docker images and orchestration for Frappe applications. -# Getting Started +## What is this? + +This repository handles the containerization of the Frappe stack, including the application server, database, Redis, and supporting services. It provides quick disposable demo setups, a development environment, production-ready Docker images and compose configurations for deploying Frappe applications including ERPNext. + +## Repository Structure + +``` +frappe_docker/ +β”œβ”€β”€ docs/ # Complete documentation +β”œβ”€β”€ overrides/ # Docker Compose configurations for different scenarios +β”œβ”€β”€ compose.yaml # Base Compose File for production setups +β”œβ”€β”€ pwd.yml # Single Compose File for quick disposable demo +β”œβ”€β”€ images/ # Dockerfiles for building Frappe images +β”œβ”€β”€ development/ # Development environment configurations +β”œβ”€β”€ devcontainer-example/ # VS Code devcontainer setup +└── resources/ # Helper scripts and configuration templates +``` + +> This section describes the structure of **this repository**, not the Frappe framework itself. + +### Key Components + +- `docs/` - Canonical documentation for all deployment and operational workflows +- `overrides/` - Opinionated Compose overrides for common deployment patterns +- `compose.yaml` - Base compose file for production setups (production) +- `pwd.yml` - Disposable demo environment (non-production) + +## Documentation + +**The official documentation for `frappe_docker` is maintained in the `docs/` folder in this repository.** **New to Frappe Docker?** Read the [Getting Started Guide](docs/getting-started.md) for a comprehensive overview of repository structure, development workflow, custom apps, Docker concepts, and quick start examples. -To get started you need [Docker](https://docs.docker.com/get-docker/), [docker-compose](https://docs.docker.com/compose/), and [git](https://docs.github.com/en/get-started/getting-started-with-git/set-up-git) setup on your machine. For Docker basics and best practices refer to Docker's [documentation](http://docs.docker.com). +If you are already familiar with Frappe, you can jump right into the [different deployment methods](docs/01-getting-started/01-choosing-a-deployment-method.md) and select the one best suited to your use case. -Once completed, chose one of the following two sections for next steps. +## Prerequisites -### Try in Play With Docker +- [Docker](https://docs.docker.com/get-docker/) +- [Docker Compose v2](https://docs.docker.com/compose/) +- [git](https://docs.github.com/en/get-started/getting-started-with-git/set-up-git) -To play in an already set up sandbox, in your browser, click the button below: +> For Docker basics and best practices refer to Docker's [documentation](http://docs.docker.com) + +## Demo setup + +The fastest way to try Frappe is to play in an already set up sandbox, in your browser, click the button below: Try in PWD -### Try on your Dev environment +### Try on your environment + +> **⚠️ Disposable demo only** +> +> **This setup is intended for quick evaluation. Expect to throw the environment away.** You will not be able to install custom apps to this setup. For production deployments, custom configurations, and detailed explanations, see the full documentation. First clone the repo: @@ -28,28 +69,15 @@ git clone https://github.com/frappe/frappe_docker cd frappe_docker ``` -Then run: `docker compose -f pwd.yml up -d` +Then run: -### To run on ARM64 architecture follow this instructions +```sh +docker compose -f pwd.yml up -d +``` -After you clone the repo and `cd frappe_docker`, run this command to build multi-architecture images specifically for ARM64. +Wait for a couple of minutes for ERPNext site to be created or check `create-site` container logs before opening browser on port `8080`. (username: `Administrator`, password: `admin`) -`docker buildx bake --no-cache --set "*.platform=linux/arm64"` - -and then - -- add `platform: linux/arm64` to all services in the `pwd.yml` -- replace the current specified versions of erpnext image on `pwd.yml` with `:latest` - -Then run: `docker compose -f pwd.yml up -d` - -## Final steps - -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`) - -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. - -# Documentation +## Documentation Links ### [Getting Started Guide](docs/getting-started.md) @@ -57,54 +85,26 @@ If you ran in a Dev Docker environment, to view container logs: `docker compose ### [Getting Started](#getting-started) -- [Quick Start (Linux/Mac)](docs/01-getting-started/01-quick-start-linux-mac.md) -- [Single Compose Setup](docs/01-getting-started/02-single-compose-setup.md) +### [Deployment Methods](docs/01-getting-started/01-choosing-a-deployment-method.md) -### [Setup](#setup) +### [ARM64](docs/01-getting-started/03-arm64.md) -- [Container Setup Overview](docs/02-setup/01-overview.md) -- [Build Setup](docs/02-setup/02-build-setup.md) -- [Start Setup](docs/02-setup/03-start-setup.md) -- [Environment Variables](docs/02-setup/04-env-variables.md) -- [Compose Overrides](docs/02-setup/05-overrides.md) -- [Setup Examples](docs/02-setup/06-setup-examples.md) -- [Single Server Example](docs/02-setup/07-single-server-example.md) +### [Container Setup Overview](docs/02-setup/01-overview.md) -### [Production](#production) +### [Development](docs/05-development/01-development.md) -- [TLS/SSL Setup](docs/03-production/01-tls-ssl-setup.md) -- [Backup Strategy](docs/03-production/02-backup-strategy.md) -- [Multi-Tenancy](docs/03-production/03-multi-tenancy.md) +## Contributing -### [Operations](#operations) - -- [Site Operations](docs/04-operations/01-site-operations.md) - -### [Development](#development) - -- [Development Guide](docs/05-development/01-development.md) -- [Debugging](docs/05-development/02-debugging.md) -- [Local Services Connection](docs/05-development/03-local-services-connection.md) - -### [Migration](#migration) - -- [Migrate from Multi-Image Setup](docs/06-migration/01-migrate-from-multi-image-setup.md) - -### [Troubleshooting](#troubleshooting) - -- [Troubleshoot Guide](docs/07-troubleshooting/01-troubleshoot.md) -- [Windows Nginx Entrypoint Error](docs/07-troubleshooting/02-windows-nginx-entrypoint-error.md) - -### [Reference](#reference) - -- [Build Version 10 Images](docs/08-reference/01-build-version-10-images.md) - -# Contributing - -If you want to contribute to this repo refer to [CONTRIBUTING.md](CONTRIBUTING.md) +Contributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines. This repository is only for container related stuff. You also might want to contribute to: -- [Frappe framework](https://github.com/frappe/frappe#contributing), -- [ERPNext](https://github.com/frappe/erpnext#contributing), +## Resources + +- [Frappe framework](https://github.com/frappe/frappe), +- [ERPNext](https://github.com/frappe/erpnext), - [Frappe Bench](https://github.com/frappe/bench). + +## License + +This repository is licensed under the MIT License. See [LICENSE](LICENSE) for details. diff --git a/docs/01-getting-started/03-quick-start-linux-mac.md b/docs/01-getting-started/03-arm64.md similarity index 92% rename from docs/01-getting-started/03-quick-start-linux-mac.md rename to docs/01-getting-started/03-arm64.md index a224e9fe..d2c50ce0 100644 --- a/docs/01-getting-started/03-quick-start-linux-mac.md +++ b/docs/01-getting-started/03-arm64.md @@ -1,18 +1,28 @@ # How to install ERPNext on linux/mac using Frappe_docker ? -step1: clone the repo +## Clone the repo -``` +```sh git clone https://github.com/frappe/frappe_docker +cd frappe_docker ``` -step2: add platform: linux/amd64 to all services in the /pwd.yaml +## buildx platform -here is the update pwd.yml file +Run this command to build multi-architecture images specifically for ARM64: + +```sh +docker buildx bake --no-cache --set "*.platform=linux/arm64" +``` + +## add platform to all services + +- add platform: `linux/arm64` to all services in the `pwd.yml` +- (replace the current specified versions of erpnext image on `pwd.yml` with `:latest`) + +here is the example pwd.yml file: ```yml -version: "3" - services: backend: image: frappe/erpnext:v15 @@ -209,14 +219,10 @@ volumes: logs: ``` -step3: run the docker +## Run the compose file -``` -cd frappe_docker -``` - -``` -docker-compose -f ./pwd.yml up +```sh +docker compose -f pwd.yml up ``` --- From 1c3439457766211815fa851437fd59986ac7d48a Mon Sep 17 00:00:00 2001 From: github-actions Date: Sat, 3 Jan 2026 10:57:08 +0000 Subject: [PATCH 084/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 162f1bc9..eebc4419 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v15.93.1 +ERPNEXT_VERSION=v15.93.2 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index fb999e5c..73747c1b 100644 --- a/pwd.yml +++ b/pwd.yml @@ -1,6 +1,6 @@ services: backend: - image: frappe/erpnext:v15.93.1 + image: frappe/erpnext:v15.93.2 networks: - frappe_network deploy: @@ -16,7 +16,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v15.93.1 + image: frappe/erpnext:v15.93.2 networks: - frappe_network deploy: @@ -45,7 +45,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v15.93.1 + image: frappe/erpnext:v15.93.2 networks: - frappe_network deploy: @@ -100,7 +100,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v15.93.1 + image: frappe/erpnext:v15.93.2 networks: - frappe_network depends_on: @@ -126,7 +126,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v15.93.1 + image: frappe/erpnext:v15.93.2 networks: - frappe_network deploy: @@ -145,7 +145,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v15.93.1 + image: frappe/erpnext:v15.93.2 networks: - frappe_network deploy: @@ -182,7 +182,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v15.93.1 + image: frappe/erpnext:v15.93.2 networks: - frappe_network deploy: @@ -196,7 +196,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v15.93.1 + image: frappe/erpnext:v15.93.2 networks: - frappe_network deploy: From 6897174970f727ce16babc5a5d686bc00f26243c Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 7 Jan 2026 05:23:32 +0000 Subject: [PATCH 085/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index eebc4419..d6e639ed 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v15.93.2 +ERPNEXT_VERSION=v15.94.0 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index 73747c1b..a147064c 100644 --- a/pwd.yml +++ b/pwd.yml @@ -1,6 +1,6 @@ services: backend: - image: frappe/erpnext:v15.93.2 + image: frappe/erpnext:v15.94.0 networks: - frappe_network deploy: @@ -16,7 +16,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v15.93.2 + image: frappe/erpnext:v15.94.0 networks: - frappe_network deploy: @@ -45,7 +45,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v15.93.2 + image: frappe/erpnext:v15.94.0 networks: - frappe_network deploy: @@ -100,7 +100,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v15.93.2 + image: frappe/erpnext:v15.94.0 networks: - frappe_network depends_on: @@ -126,7 +126,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v15.93.2 + image: frappe/erpnext:v15.94.0 networks: - frappe_network deploy: @@ -145,7 +145,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v15.93.2 + image: frappe/erpnext:v15.94.0 networks: - frappe_network deploy: @@ -182,7 +182,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v15.93.2 + image: frappe/erpnext:v15.94.0 networks: - frappe_network deploy: @@ -196,7 +196,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v15.93.2 + image: frappe/erpnext:v15.94.0 networks: - frappe_network deploy: From 184499f99814c90b1055a00f4b5acae911869748 Mon Sep 17 00:00:00 2001 From: github-actions Date: Thu, 8 Jan 2026 08:43:10 +0000 Subject: [PATCH 086/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index d6e639ed..1e1a7f2b 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v15.94.0 +ERPNEXT_VERSION=v15.94.1 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index a147064c..522851d2 100644 --- a/pwd.yml +++ b/pwd.yml @@ -1,6 +1,6 @@ services: backend: - image: frappe/erpnext:v15.94.0 + image: frappe/erpnext:v15.94.1 networks: - frappe_network deploy: @@ -16,7 +16,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v15.94.0 + image: frappe/erpnext:v15.94.1 networks: - frappe_network deploy: @@ -45,7 +45,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v15.94.0 + image: frappe/erpnext:v15.94.1 networks: - frappe_network deploy: @@ -100,7 +100,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v15.94.0 + image: frappe/erpnext:v15.94.1 networks: - frappe_network depends_on: @@ -126,7 +126,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v15.94.0 + image: frappe/erpnext:v15.94.1 networks: - frappe_network deploy: @@ -145,7 +145,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v15.94.0 + image: frappe/erpnext:v15.94.1 networks: - frappe_network deploy: @@ -182,7 +182,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v15.94.0 + image: frappe/erpnext:v15.94.1 networks: - frappe_network deploy: @@ -196,7 +196,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v15.94.0 + image: frappe/erpnext:v15.94.1 networks: - frappe_network deploy: From f5fc7b40aebc63eab99219216414ffa35b167c3c Mon Sep 17 00:00:00 2001 From: Revant Nandgaonkar Date: Tue, 13 Jan 2026 13:52:46 +0530 Subject: [PATCH 087/279] feat: publish version 16 for helm chart (#1758) --- .github/workflows/build_stable.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_stable.yml b/.github/workflows/build_stable.yml index 0f1b8cfb..ab6469de 100644 --- a/.github/workflows/build_stable.yml +++ b/.github/workflows/build_stable.yml @@ -125,4 +125,4 @@ jobs: run: | git clone git@github.com:frappe/helm.git && cd helm pip install -r release_wizard/requirements.txt - ./release_wizard/wizard 15 patch --remote origin --ci + ./release_wizard/wizard 16 patch --remote origin --ci From 56c6520e2905b2bdaf981db9293b20a4408e520d Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 13 Jan 2026 15:11:17 +0000 Subject: [PATCH 088/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 1e1a7f2b..446e028d 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v15.94.1 +ERPNEXT_VERSION=v15.94.2 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index 522851d2..8f082f32 100644 --- a/pwd.yml +++ b/pwd.yml @@ -1,6 +1,6 @@ services: backend: - image: frappe/erpnext:v15.94.1 + image: frappe/erpnext:v15.94.2 networks: - frappe_network deploy: @@ -16,7 +16,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v15.94.1 + image: frappe/erpnext:v15.94.2 networks: - frappe_network deploy: @@ -45,7 +45,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v15.94.1 + image: frappe/erpnext:v15.94.2 networks: - frappe_network deploy: @@ -100,7 +100,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v15.94.1 + image: frappe/erpnext:v15.94.2 networks: - frappe_network depends_on: @@ -126,7 +126,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v15.94.1 + image: frappe/erpnext:v15.94.2 networks: - frappe_network deploy: @@ -145,7 +145,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v15.94.1 + image: frappe/erpnext:v15.94.2 networks: - frappe_network deploy: @@ -182,7 +182,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v15.94.1 + image: frappe/erpnext:v15.94.2 networks: - frappe_network deploy: @@ -196,7 +196,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v15.94.1 + image: frappe/erpnext:v15.94.2 networks: - frappe_network deploy: From bc254c2b4ceb9d01dbdd598ace2053326120d27f Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 14 Jan 2026 12:42:50 +0000 Subject: [PATCH 089/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 446e028d..5d58a451 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v15.94.2 +ERPNEXT_VERSION=v15.94.3 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index 8f082f32..e2ca0344 100644 --- a/pwd.yml +++ b/pwd.yml @@ -1,6 +1,6 @@ services: backend: - image: frappe/erpnext:v15.94.2 + image: frappe/erpnext:v15.94.3 networks: - frappe_network deploy: @@ -16,7 +16,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v15.94.2 + image: frappe/erpnext:v15.94.3 networks: - frappe_network deploy: @@ -45,7 +45,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v15.94.2 + image: frappe/erpnext:v15.94.3 networks: - frappe_network deploy: @@ -100,7 +100,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v15.94.2 + image: frappe/erpnext:v15.94.3 networks: - frappe_network depends_on: @@ -126,7 +126,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v15.94.2 + image: frappe/erpnext:v15.94.3 networks: - frappe_network deploy: @@ -145,7 +145,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v15.94.2 + image: frappe/erpnext:v15.94.3 networks: - frappe_network deploy: @@ -182,7 +182,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v15.94.2 + image: frappe/erpnext:v15.94.3 networks: - frappe_network deploy: @@ -196,7 +196,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v15.94.2 + image: frappe/erpnext:v15.94.3 networks: - frappe_network deploy: From 8afa5d60f522a62c4d3ecc76a7d1da7634cdb840 Mon Sep 17 00:00:00 2001 From: Rocket-Quack <202538874+Rocket-Quack@users.noreply.github.com> Date: Fri, 16 Jan 2026 12:52:20 +0100 Subject: [PATCH 090/279] chore(traefik): migrate compose overrides to v3 traefik --- overrides/compose.custom-domain.yaml | 3 +- overrides/compose.https.yaml | 57 ++++++++-------- overrides/compose.multi-bench-ssl.yaml | 5 +- overrides/compose.multi-bench.yaml | 3 +- overrides/compose.proxy.yaml | 33 +++++----- overrides/compose.traefik-ssl.yaml | 91 +++++++++++++------------- overrides/compose.traefik.yaml | 81 ++++++++++++----------- 7 files changed, 140 insertions(+), 133 deletions(-) diff --git a/overrides/compose.custom-domain.yaml b/overrides/compose.custom-domain.yaml index e7c82f90..7ca31776 100644 --- a/overrides/compose.custom-domain.yaml +++ b/overrides/compose.custom-domain.yaml @@ -14,7 +14,8 @@ services: - traefik.http.services.${ROUTER?ROUTER not set}.loadbalancer.server.port=2016 - traefik.http.routers.${ROUTER}.service=${ROUTER} - traefik.http.routers.${ROUTER}.entrypoints=http - - traefik.http.routers.${ROUTER}.rule=Host(${SITES?SITES not set}) + - traefik.http.routers.${ROUTER}.ruleSyntax=v3 + - traefik.http.routers.${ROUTER}.rule=${SITES_RULE?SITES_RULE not set} - traefik.http.middlewares.${ROUTER}.headers.customrequestheaders.Host=${BASE_SITE?BASE_SITE not set} - traefik.http.routers.${ROUTER}.middlewares=${ROUTER} networks: diff --git a/overrides/compose.https.yaml b/overrides/compose.https.yaml index 9096e560..55b453e8 100644 --- a/overrides/compose.https.yaml +++ b/overrides/compose.https.yaml @@ -1,32 +1,33 @@ -services: - frontend: - labels: +services: + frontend: + labels: - traefik.enable=true - traefik.http.services.frontend.loadbalancer.server.port=8080 - traefik.http.routers.frontend-http.entrypoints=websecure - traefik.http.routers.frontend-http.tls.certresolver=main-resolver - - traefik.http.routers.frontend-http.rule=Host(${SITES:?List of sites not set}) - - proxy: - image: traefik:v2.11 - restart: unless-stopped - command: - - --providers.docker=true - - --providers.docker.exposedbydefault=false - - --entrypoints.web.address=:80 - - --entrypoints.web.http.redirections.entrypoint.to=websecure - - --entrypoints.web.http.redirections.entrypoint.scheme=https - - --entrypoints.websecure.address=:443 - - --certificatesResolvers.main-resolver.acme.httpChallenge=true - - --certificatesResolvers.main-resolver.acme.httpChallenge.entrypoint=web - - --certificatesResolvers.main-resolver.acme.email=${LETSENCRYPT_EMAIL:?No Let's Encrypt email set} - - --certificatesResolvers.main-resolver.acme.storage=/letsencrypt/acme.json - ports: - - ${HTTP_PUBLISH_PORT:-80}:80 - - ${HTTPS_PUBLISH_PORT:-443}:443 - volumes: - - cert-data:/letsencrypt - - /var/run/docker.sock:/var/run/docker.sock:ro - -volumes: - cert-data: + - traefik.http.routers.frontend-http.ruleSyntax=v3 + - traefik.http.routers.frontend-http.rule=${SITES_RULE:?SITES_RULE not set} + + proxy: + image: traefik:v3.6 + restart: unless-stopped + command: + - --providers.docker=true + - --providers.docker.exposedbydefault=false + - --entrypoints.web.address=:80 + - --entrypoints.web.http.redirections.entrypoint.to=websecure + - --entrypoints.web.http.redirections.entrypoint.scheme=https + - --entrypoints.websecure.address=:443 + - --certificatesResolvers.main-resolver.acme.httpChallenge=true + - --certificatesResolvers.main-resolver.acme.httpChallenge.entrypoint=web + - --certificatesResolvers.main-resolver.acme.email=${LETSENCRYPT_EMAIL:?No Let's Encrypt email set} + - --certificatesResolvers.main-resolver.acme.storage=/letsencrypt/acme.json + ports: + - ${HTTP_PUBLISH_PORT:-80}:80 + - ${HTTPS_PUBLISH_PORT:-443}:443 + volumes: + - cert-data:/letsencrypt + - /var/run/docker.sock:/var/run/docker.sock:ro + +volumes: + cert-data: diff --git a/overrides/compose.multi-bench-ssl.yaml b/overrides/compose.multi-bench-ssl.yaml index 158d22bd..e38da19b 100644 --- a/overrides/compose.multi-bench-ssl.yaml +++ b/overrides/compose.multi-bench-ssl.yaml @@ -4,8 +4,9 @@ services: # ${ROUTER}-http to use the middleware to redirect to https - traefik.http.routers.${ROUTER}-http.middlewares=https-redirect # ${ROUTER}-https the actual router using HTTPS - # Uses the environment variable SITES - - traefik.http.routers.${ROUTER}-https.rule=Host(${SITES?SITES not set}) + # Uses the environment variable SITES_RULE + - traefik.http.routers.${ROUTER}-https.ruleSyntax=v3 + - traefik.http.routers.${ROUTER}-https.rule=${SITES_RULE?SITES_RULE not set} - traefik.http.routers.${ROUTER}-https.entrypoints=https - traefik.http.routers.${ROUTER}-https.tls=true # Use the service ${ROUTER} with the frontend diff --git a/overrides/compose.multi-bench.yaml b/overrides/compose.multi-bench.yaml index 7e681a18..542e7716 100644 --- a/overrides/compose.multi-bench.yaml +++ b/overrides/compose.multi-bench.yaml @@ -9,7 +9,8 @@ services: - traefik.http.services.${ROUTER?ROUTER not set}.loadbalancer.server.port=8080 - traefik.http.routers.${ROUTER}-http.service=${ROUTER} - traefik.http.routers.${ROUTER}-http.entrypoints=http - - traefik.http.routers.${ROUTER}-http.rule=Host(${SITES?SITES not set}) + - traefik.http.routers.${ROUTER}-http.ruleSyntax=v3 + - traefik.http.routers.${ROUTER}-http.rule=${SITES_RULE?SITES_RULE not set} configurator: networks: - bench-network diff --git a/overrides/compose.proxy.yaml b/overrides/compose.proxy.yaml index 32ce9fab..b3c467c7 100644 --- a/overrides/compose.proxy.yaml +++ b/overrides/compose.proxy.yaml @@ -1,19 +1,20 @@ -services: - frontend: - labels: +services: + frontend: + labels: - traefik.enable=true - traefik.http.services.frontend.loadbalancer.server.port=8080 - traefik.http.routers.frontend-http.entrypoints=web - - traefik.http.routers.frontend-http.rule=HostRegexp(`{any:.+}`) - - proxy: - image: traefik:v2.11 - command: - - --providers.docker - - --providers.docker.exposedbydefault=false - - --entrypoints.web.address=:80 - ports: - - ${HTTP_PUBLISH_PORT:-80}:80 - volumes: - - /var/run/docker.sock:/var/run/docker.sock:ro - userns_mode: host + - traefik.http.routers.frontend-http.ruleSyntax=v3 + - traefik.http.routers.frontend-http.rule=HostRegexp(`^.+$`) + + proxy: + image: traefik:v3.6 + command: + - --providers.docker + - --providers.docker.exposedbydefault=false + - --entrypoints.web.address=:80 + ports: + - ${HTTP_PUBLISH_PORT:-80}:80 + volumes: + - /var/run/docker.sock:/var/run/docker.sock:ro + userns_mode: host diff --git a/overrides/compose.traefik-ssl.yaml b/overrides/compose.traefik-ssl.yaml index b83cb8e4..19083bf2 100644 --- a/overrides/compose.traefik-ssl.yaml +++ b/overrides/compose.traefik-ssl.yaml @@ -1,48 +1,49 @@ -services: - traefik: - labels: - # https-redirect middleware to redirect HTTP to HTTPS - # It can be reused by other stacks in other Docker Compose files - - traefik.http.middlewares.https-redirect.redirectscheme.scheme=https - - traefik.http.middlewares.https-redirect.redirectscheme.permanent=true - # traefik-http to use the middleware to redirect to https - - traefik.http.routers.traefik-public-http.middlewares=https-redirect +services: + traefik: + labels: + # https-redirect middleware to redirect HTTP to HTTPS + # It can be reused by other stacks in other Docker Compose files + - traefik.http.middlewares.https-redirect.redirectscheme.scheme=https + - traefik.http.middlewares.https-redirect.redirectscheme.permanent=true + # traefik-http to use the middleware to redirect to https + - traefik.http.routers.traefik-public-http.middlewares=https-redirect # traefik-https the actual router using HTTPS # Uses the environment variable DOMAIN + - traefik.http.routers.traefik-public-https.ruleSyntax=v3 - traefik.http.routers.traefik-public-https.rule=Host(`${TRAEFIK_DOMAIN}`) - - traefik.http.routers.traefik-public-https.entrypoints=https - - traefik.http.routers.traefik-public-https.tls=true - # Use the special Traefik service api@internal with the web UI/Dashboard - - traefik.http.routers.traefik-public-https.service=api@internal - # Use the "le" (Let's Encrypt) resolver created below - - traefik.http.routers.traefik-public-https.tls.certresolver=le - # Enable HTTP Basic auth, using the middleware created above - - traefik.http.routers.traefik-public-https.middlewares=admin-auth - command: - # Enable Docker in Traefik, so that it reads labels from Docker services - - --providers.docker=true - # Do not expose all Docker services, only the ones explicitly exposed - - --providers.docker.exposedbydefault=false - # Create an entrypoint http listening on port 80 - - --entrypoints.http.address=:80 - # Create an entrypoint https listening on port 443 - - --entrypoints.https.address=:443 - # Create the certificate resolver le for Let's Encrypt, uses the environment variable EMAIL - - --certificatesresolvers.le.acme.email=${EMAIL:?No EMAIL set} - # Store the Let's Encrypt certificates in the mounted volume - - --certificatesresolvers.le.acme.storage=/certificates/acme.json - # Use the TLS Challenge for Let's Encrypt - - --certificatesresolvers.le.acme.tlschallenge=true - # Enable the access log, with HTTP requests - - --accesslog - # Enable the Traefik log, for configurations and errors - - --log - # Enable the Dashboard and API - - --api - ports: - - ${HTTPS_PUBLISH_PORT:-443}:443 - volumes: - - cert-data:/certificates - -volumes: - cert-data: + - traefik.http.routers.traefik-public-https.entrypoints=https + - traefik.http.routers.traefik-public-https.tls=true + # Use the special Traefik service api@internal with the web UI/Dashboard + - traefik.http.routers.traefik-public-https.service=api@internal + # Use the "le" (Let's Encrypt) resolver created below + - traefik.http.routers.traefik-public-https.tls.certresolver=le + # Enable HTTP Basic auth, using the middleware created above + - traefik.http.routers.traefik-public-https.middlewares=admin-auth + command: + # Enable Docker in Traefik, so that it reads labels from Docker services + - --providers.docker=true + # Do not expose all Docker services, only the ones explicitly exposed + - --providers.docker.exposedbydefault=false + # Create an entrypoint http listening on port 80 + - --entrypoints.http.address=:80 + # Create an entrypoint https listening on port 443 + - --entrypoints.https.address=:443 + # Create the certificate resolver le for Let's Encrypt, uses the environment variable EMAIL + - --certificatesresolvers.le.acme.email=${EMAIL:?No EMAIL set} + # Store the Let's Encrypt certificates in the mounted volume + - --certificatesresolvers.le.acme.storage=/certificates/acme.json + # Use the TLS Challenge for Let's Encrypt + - --certificatesresolvers.le.acme.tlschallenge=true + # Enable the access log, with HTTP requests + - --accesslog + # Enable the Traefik log, for configurations and errors + - --log + # Enable the Dashboard and API + - --api + ports: + - ${HTTPS_PUBLISH_PORT:-443}:443 + volumes: + - cert-data:/certificates + +volumes: + cert-data: diff --git a/overrides/compose.traefik.yaml b/overrides/compose.traefik.yaml index 7765e19d..01ad3c5f 100644 --- a/overrides/compose.traefik.yaml +++ b/overrides/compose.traefik.yaml @@ -1,45 +1,46 @@ -services: - traefik: - image: "traefik:v2.11" - restart: unless-stopped - labels: - # Enable Traefik for this service, to make it available in the public network - - traefik.enable=true - # Use the traefik-public network (declared below) - - traefik.docker.network=traefik-public +services: + traefik: + image: "traefik:v3.6" + restart: unless-stopped + labels: + # Enable Traefik for this service, to make it available in the public network + - traefik.enable=true + # Use the traefik-public network (declared below) + - traefik.docker.network=traefik-public # admin-auth middleware with HTTP Basic auth # Using the environment variables USERNAME and HASHED_PASSWORD - traefik.http.middlewares.admin-auth.basicauth.users=admin:${HASHED_PASSWORD:?No HASHED_PASSWORD set} # Uses the environment variable TRAEFIK_DOMAIN + - traefik.http.routers.traefik-public-http.ruleSyntax=v3 - traefik.http.routers.traefik-public-http.rule=Host(`${TRAEFIK_DOMAIN:?No TRAEFIK_DOMAIN set}`) - - traefik.http.routers.traefik-public-http.entrypoints=http - # Use the special Traefik service api@internal with the web UI/Dashboard - - traefik.http.routers.traefik-public-http.service=api@internal - # Enable HTTP Basic auth, using the middleware created above - - traefik.http.routers.traefik-public-http.middlewares=admin-auth - # Define the port inside of the Docker service to use - - traefik.http.services.traefik-public.loadbalancer.server.port=8080 - command: - # Enable Docker in Traefik, so that it reads labels from Docker services - - --providers.docker=true - # Do not expose all Docker services, only the ones explicitly exposed - - --providers.docker.exposedbydefault=false - # Create an entrypoint http listening on port 80 - - --entrypoints.http.address=:80 - # Enable the access log, with HTTP requests - - --accesslog - # Enable the Traefik log, for configurations and errors - - --log - # Enable the Dashboard and API - - --api - ports: - - ${HTTP_PUBLISH_PORT:-80}:80 - volumes: - - /var/run/docker.sock:/var/run/docker.sock:ro - networks: - - traefik-public - -networks: - traefik-public: - name: traefik-public - external: false + - traefik.http.routers.traefik-public-http.entrypoints=http + # Use the special Traefik service api@internal with the web UI/Dashboard + - traefik.http.routers.traefik-public-http.service=api@internal + # Enable HTTP Basic auth, using the middleware created above + - traefik.http.routers.traefik-public-http.middlewares=admin-auth + # Define the port inside of the Docker service to use + - traefik.http.services.traefik-public.loadbalancer.server.port=8080 + command: + # Enable Docker in Traefik, so that it reads labels from Docker services + - --providers.docker=true + # Do not expose all Docker services, only the ones explicitly exposed + - --providers.docker.exposedbydefault=false + # Create an entrypoint http listening on port 80 + - --entrypoints.http.address=:80 + # Enable the access log, with HTTP requests + - --accesslog + # Enable the Traefik log, for configurations and errors + - --log + # Enable the Dashboard and API + - --api + ports: + - ${HTTP_PUBLISH_PORT:-80}:80 + volumes: + - /var/run/docker.sock:/var/run/docker.sock:ro + networks: + - traefik-public + +networks: + traefik-public: + name: traefik-public + external: false From 108fb0e6af7ce572c29e054a5f2ff85e267ef954 Mon Sep 17 00:00:00 2001 From: Rocket-Quack <202538874+Rocket-Quack@users.noreply.github.com> Date: Fri, 16 Jan 2026 12:53:48 +0100 Subject: [PATCH 091/279] docs(env): switch SITES to SITES_RULE for v3 traefik --- example.env | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/example.env b/example.env index 5d58a451..a1d0f520 100644 --- a/example.env +++ b/example.env @@ -49,7 +49,8 @@ PROXY_READ_TIMEOUT= # Necessary if the upload limit in the frappe application is increased CLIENT_MAX_BODY_SIZE= -# List of sites for letsencrypt certificates quoted with backtick (`) and separated by comma (,) +# Single site: SITES_RULE=Host(`erp.example.com`) +# Multiple sites: SITES_RULE=Host(`a.example.com`) || Host(`b.example.com`) # More https://doc.traefik.io/traefik/routing/routers/#rule # About acme https://doc.traefik.io/traefik/https/acme/#domain-definition -SITES=`erp.example.com` +SITES_RULE=Host(`erp.example.com`) From 9a4a078bdeec08c78545b423bd3e971e41f3cf28 Mon Sep 17 00:00:00 2001 From: Rocket-Quack <202538874+Rocket-Quack@users.noreply.github.com> Date: Fri, 16 Jan 2026 13:04:34 +0100 Subject: [PATCH 092/279] docs: update Traefik v3 SITES_RULE usage and examples --- docs/02-setup/04-env-variables.md | 10 +++++----- docs/02-setup/05-overrides.md | 2 +- docs/02-setup/06-setup-examples.md | 4 ++-- docs/02-setup/07-single-server-example.md | 8 ++++---- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/02-setup/04-env-variables.md b/docs/02-setup/04-env-variables.md index 1001c888..c566ecd9 100644 --- a/docs/02-setup/04-env-variables.md +++ b/docs/02-setup/04-env-variables.md @@ -48,16 +48,16 @@ Then edit `.env` and set variables according to your needs. | Variable | Purpose | Default | When to Set | | ------------------- | ------------------------------------------------ | ------- | ---------------------------------------- | | `LETSENCRYPT_EMAIL` | Email for Let's Encrypt certificate registration | β€” | Required if using HTTPS override | -| `SITES` | List of domains for SSL certificates | β€” | Required if using reverse proxy override | +| `SITES_RULE` | List of domains for SSL (Traefik rule for TLS domain routing) | β€” | Required if using reverse proxy override | -**Format for `SITES`:** +**Format for `SITES_RULE`:** ```bash # Single site -SITES=`mysite.example.com` +SITES_RULE=Host(`mysite.example.com`) -# Wildcard (any subdomain) -SITES=`{any:.+}` +# Multiple sites +SITES_RULE=Host(`a.example.com`) || Host(`b.example.com`) ``` --- diff --git a/docs/02-setup/05-overrides.md b/docs/02-setup/05-overrides.md index 9188489d..156a6834 100644 --- a/docs/02-setup/05-overrides.md +++ b/docs/02-setup/05-overrides.md @@ -14,7 +14,7 @@ docker compose -f compose.yaml -f overrides/compose.mariadb.yaml -f overrides/co | **Proxy** | | | | compose.noproxy.yaml | Exposes the application directly on port `:8080` without a reverse proxy | | | compose.proxy.yaml | Uses Traefik as HTTP reverse proxy on port `:80` | You can change the published port by setting `HTTP_PUBLISH_PORT` | -| compose.https.yaml | Uses Traefik as HTTPS reverse proxy on Port `:443` with automatic HTTP-to-HTTPS redirect | `SITES` and `LETSENCRYPT_EMAIL` must be set. `HTTP_PUBLISH_PORT` and `HTTPS_PUBLISH_PORT` can be set. | +| compose.https.yaml | Uses Traefik as HTTPS reverse proxy on Port `:443` with automatic HTTP-to-HTTPS redirect | `SITES_RULE` and `LETSENCRYPT_EMAIL` must be set. `HTTP_PUBLISH_PORT` and `HTTPS_PUBLISH_PORT` can be set. | | **Redis** | | | | compose.redis.yaml | Adds Redis service for caching and background job queuing | | **TBD** | **The following overrides are available but lack documentation. If you use them and understand their purpose, please consider contributing to this documentation.** | diff --git a/docs/02-setup/06-setup-examples.md b/docs/02-setup/06-setup-examples.md index becf9442..5d9b569a 100644 --- a/docs/02-setup/06-setup-examples.md +++ b/docs/02-setup/06-setup-examples.md @@ -78,7 +78,7 @@ Setup Frappe/ERPNext using containerized MariaDB and Redis with Let's Encrypt SS **Requirements:** -- Set `LETSENCRYPT_EMAIL` and `SITES` environment variables +- Set `LETSENCRYPT_EMAIL` and `SITES_RULE` environment variables - DNS must point to your server IP ```sh @@ -93,7 +93,7 @@ docker compose -f compose.yaml \ docker compose --project-name -f ~/gitops/docker-compose.yml up -d ``` -> **Note:** Ensure your `SITES` variable is properly formatted. See [environment variables](04-env-variables.md) for the correct format. +> **Note:** Ensure your `SITES_RULE` variable is properly formatted. See [environment variables](04-env-variables.md) for the correct format. ## Create First Site diff --git a/docs/02-setup/07-single-server-example.md b/docs/02-setup/07-single-server-example.md index d4a459c9..6827dda6 100644 --- a/docs/02-setup/07-single-server-example.md +++ b/docs/02-setup/07-single-server-example.md @@ -142,7 +142,7 @@ cp example.env ~/gitops/erpnext-one.env sed -i 's/DB_PASSWORD=123/DB_PASSWORD=changeit/g' ~/gitops/erpnext-one.env sed -i 's/DB_HOST=/DB_HOST=mariadb-database/g' ~/gitops/erpnext-one.env sed -i 's/DB_PORT=/DB_PORT=3306/g' ~/gitops/erpnext-one.env -sed -i 's/SITES=`erp.example.com`/SITES=\`one.example.com\`,\`two.example.com\`/g' ~/gitops/erpnext-one.env +sed -i 's/SITES_RULE=Host(`erp.example.com`)/SITES_RULE=Host(`one.example.com`) || Host(`two.example.com`)/g' ~/gitops/erpnext-one.env echo 'ROUTER=erpnext-one' >> ~/gitops/erpnext-one.env echo "BENCH_NETWORK=erpnext-one" >> ~/gitops/erpnext-one.env ``` @@ -204,7 +204,7 @@ sed -i 's/DB_PASSWORD=123/DB_PASSWORD=changeit/g' ~/gitops/erpnext-two.env sed -i 's/DB_HOST=/DB_HOST=mariadb-database/g' ~/gitops/erpnext-two.env sed -i 's/DB_PORT=/DB_PORT=3306/g' ~/gitops/erpnext-two.env echo "ROUTER=erpnext-two" >> ~/gitops/erpnext-two.env -echo "SITES=\`three.example.com\`,\`four.example.com\`" >> ~/gitops/erpnext-two.env +echo 'SITES_RULE=Host(`three.example.com`) || Host(`four.example.com`)' >> ~/gitops/erpnext-two.env echo "BENCH_NETWORK=erpnext-two" >> ~/gitops/erpnext-two.env ``` @@ -253,7 +253,7 @@ Create environment file ```shell echo "ROUTER=custom-one-example" > ~/gitops/custom-one-example.env -echo "SITES=\`custom-one.example.com\`" >> ~/gitops/custom-one-example.env +echo 'SITES_RULE=Host(`custom-one.example.com`)' >> ~/gitops/custom-one-example.env echo "BASE_SITE=one.example.com" >> ~/gitops/custom-one-example.env echo "BENCH_NETWORK=erpnext-one" >> ~/gitops/custom-one-example.env ``` @@ -262,7 +262,7 @@ Note: - Change the file name from `custom-one-example.env` to a logical one. - Change `ROUTER` variable from `custom-one.example.com` to the one being added. -- Change `SITES` variable from `custom-one.example.com` to the one being added. You can add multiple sites quoted in backtick (`) and separated by commas. +- Change `SITES_RULE` variable to the one being added. You can add multiple sites with `Host(...) || Host(...)`. - Change `BASE_SITE` variable from `one.example.com` to the one which is being pointed to. - Change `BENCH_NETWORK` variable from `erpnext-one` to the one which was created with the bench. From c5525bf021446a843eb38f6ec3260055172d278b Mon Sep 17 00:00:00 2001 From: Rocket-Quack <202538874+Rocket-Quack@users.noreply.github.com> Date: Fri, 16 Jan 2026 13:27:10 +0100 Subject: [PATCH 093/279] docs: add Traefik v2 to v3 migration guide --- docs/06-migration/02-traefik-v3-migration.md | 70 ++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 docs/06-migration/02-traefik-v3-migration.md diff --git a/docs/06-migration/02-traefik-v3-migration.md b/docs/06-migration/02-traefik-v3-migration.md new file mode 100644 index 00000000..9e4ed21f --- /dev/null +++ b/docs/06-migration/02-traefik-v3-migration.md @@ -0,0 +1,70 @@ +# Migrate an existing Traefik v2 instance to v3 + +Use this guide if you already run Traefik v2 with `frappe_docker` and want to upgrade to v3. It focuses on the image upgrade and the v3 routing rule changes that affect existing setups. + +### Before you start +Before migrating anything, it is always recommended to create a backup. Better safe than sorry. In particular, compose and .env should be backed up. + +### Quick upgrade summary + +1) Pull the updated repo +2) Update env variables especially the updated `SITES` to `SITES_RULE` +3) Regenerate the compose config and restart the stack + +#### Multiple hostnames + +v2 allowed comma-separated host lists inside `Host(...)`. In v3 traefik uses logical OR + +**Before (v2):** +``` +Host(`a.example.com`,`b.example.com`) +``` + +**After (v3):** +``` +Host(`a.example.com`) || Host(`b.example.com`) +``` + +### Step 1: Replace `SITES` with `SITES_RULE` + +All Traefik routing for HTTPS and multi-bench setups now uses `SITES_RULE`, which is a full v3 rule expression + +**Single site:** +``` +SITES_RULE=Host(`erp.example.com`) +``` + +**Multiple sites:** +``` +SITES_RULE=Host(`a.example.com`) || Host(`b.example.com`) +``` + +### Step 2: Regenerate and start your compose config + +Example for HTTPS: + +```sh +docker compose --env-file .env \ + -f compose.yaml \ + -f overrides/compose.mariadb.yaml \ + -f overrides/compose.redis.yaml \ + -f overrides/compose.https.yaml \ + config > ~/gitops/docker-compose.yml +``` +```sh +docker compose --project-name -f ~/gitops/docker-compose.yml up -d +``` + +See [Single Server Example](../02-setup/07-single-server-example.md) + +### Step 3: Verify Traefik + +After restarting, Traefik will be used in the new supported version 3.6 and the same URLs will be used for the instances when making adjustments. After that, the pages should be accessible as before via the proxy and, if using HTTPS, via HTTPS. + +### Rollback + +If you need to rollback: + +1) Revert Traefik image to `v2.11` +2) Restore the old `SITES` variable format and v2 rules +3) Regenerate the compose config and restart From 81ca6ca52292447347614f98ef6c37568ba845c0 Mon Sep 17 00:00:00 2001 From: Rocket-Quack <202538874+Rocket-Quack@users.noreply.github.com> Date: Mon, 19 Jan 2026 15:23:06 +0100 Subject: [PATCH 094/279] chore(traefik): usage of v3 traefik with v2 rule syntax --- overrides/compose.https.yaml | 5 ++++- overrides/compose.proxy.yaml | 5 ++++- overrides/compose.traefik-ssl.yaml | 3 +++ overrides/compose.traefik.yaml | 5 ++++- 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/overrides/compose.https.yaml b/overrides/compose.https.yaml index 9096e560..66ca8d06 100644 --- a/overrides/compose.https.yaml +++ b/overrides/compose.https.yaml @@ -8,11 +8,14 @@ services: - traefik.http.routers.frontend-http.rule=Host(${SITES:?List of sites not set}) proxy: - image: traefik:v2.11 + image: traefik:v3.6 restart: unless-stopped command: - --providers.docker=true - --providers.docker.exposedbydefault=false + # Keep v2 rule syntax for now + # Ensure compatibility with existing labels (will be removed if v3 transistion is complete) + - --core.defaultRuleSyntax=v2 - --entrypoints.web.address=:80 - --entrypoints.web.http.redirections.entrypoint.to=websecure - --entrypoints.web.http.redirections.entrypoint.scheme=https diff --git a/overrides/compose.proxy.yaml b/overrides/compose.proxy.yaml index 32ce9fab..39b36749 100644 --- a/overrides/compose.proxy.yaml +++ b/overrides/compose.proxy.yaml @@ -7,10 +7,13 @@ services: - traefik.http.routers.frontend-http.rule=HostRegexp(`{any:.+}`) proxy: - image: traefik:v2.11 + image: traefik:v3.6 command: - --providers.docker - --providers.docker.exposedbydefault=false + # Keep v2 rule syntax for now + # Ensure compatibility with existing labels (will be removed if v3 transistion is complete) + - --core.defaultRuleSyntax=v2 - --entrypoints.web.address=:80 ports: - ${HTTP_PUBLISH_PORT:-80}:80 diff --git a/overrides/compose.traefik-ssl.yaml b/overrides/compose.traefik-ssl.yaml index b83cb8e4..1c3a0ad2 100644 --- a/overrides/compose.traefik-ssl.yaml +++ b/overrides/compose.traefik-ssl.yaml @@ -23,6 +23,9 @@ services: - --providers.docker=true # Do not expose all Docker services, only the ones explicitly exposed - --providers.docker.exposedbydefault=false + # Keep v2 rule syntax for now + # Ensure compatibility with existing labels (will be removed if v3 transistion is complete) + - --core.defaultRuleSyntax=v2 # Create an entrypoint http listening on port 80 - --entrypoints.http.address=:80 # Create an entrypoint https listening on port 443 diff --git a/overrides/compose.traefik.yaml b/overrides/compose.traefik.yaml index 7765e19d..1846597f 100644 --- a/overrides/compose.traefik.yaml +++ b/overrides/compose.traefik.yaml @@ -1,6 +1,6 @@ services: traefik: - image: "traefik:v2.11" + image: "traefik:v3.6" restart: unless-stopped labels: # Enable Traefik for this service, to make it available in the public network @@ -24,6 +24,9 @@ services: - --providers.docker=true # Do not expose all Docker services, only the ones explicitly exposed - --providers.docker.exposedbydefault=false + # Keep v2 rule syntax for now + # Ensure compatibility with existing labels (will be removed if v3 transistion is complete) + - --core.defaultRuleSyntax=v2 # Create an entrypoint http listening on port 80 - --entrypoints.http.address=:80 # Enable the access log, with HTTP requests From 166a9040414d522a9d7ea2faf0f53b17cad21931 Mon Sep 17 00:00:00 2001 From: Rocket-Quack <202538874+Rocket-Quack@users.noreply.github.com> Date: Mon, 19 Jan 2026 15:24:43 +0100 Subject: [PATCH 095/279] docs: deprecation note for SITES in favor of SITES_RULE for v3 traefik --- docs/02-setup/04-env-variables.md | 4 ++++ docs/02-setup/05-overrides.md | 2 ++ 2 files changed, 6 insertions(+) diff --git a/docs/02-setup/04-env-variables.md b/docs/02-setup/04-env-variables.md index 1001c888..c49cdc50 100644 --- a/docs/02-setup/04-env-variables.md +++ b/docs/02-setup/04-env-variables.md @@ -60,6 +60,10 @@ SITES=`mysite.example.com` SITES=`{any:.+}` ``` +>Note: `SITES` currently supplies the host list that goes into the `Host(...)` rules. Once the Traefik v3 transition is completed, the plan is to switch to `SITES_RULE` (full rule expression) and deprecate `SITES` to map the Traefik Rule Syntax. + +>Currently the used syntax is pinned to v2 via `--core.defaultRuleSyntax=v2`). + --- ## Site Configuration diff --git a/docs/02-setup/05-overrides.md b/docs/02-setup/05-overrides.md index 9188489d..783868f7 100644 --- a/docs/02-setup/05-overrides.md +++ b/docs/02-setup/05-overrides.md @@ -4,6 +4,8 @@ Overrides extend the base compose.yaml with additional services or modify existi docker compose -f compose.yaml -f overrides/compose.mariadb.yaml -f overrides/compose.redis.yaml config > compose.custom.yaml ``` +Note: The Traefik-based overrides uses Traefik v3.6 and `--core.defaultRuleSyntax=v2` for compatibility with existing traefik v2.11. This flag is temporary and will be removed once the transition to v3.6 is completed. + | Overrider | Purpose | Additional Info | | ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | | **Database** | | | From a6e92bf984f5b1f22c0b82efd4b85644daf716f5 Mon Sep 17 00:00:00 2001 From: Rocket-Quack <202538874+Rocket-Quack@users.noreply.github.com> Date: Mon, 19 Jan 2026 17:36:49 +0100 Subject: [PATCH 096/279] fix(lint): Traefik transition comment typo --- overrides/compose.https.yaml | 2 +- overrides/compose.proxy.yaml | 2 +- overrides/compose.traefik-ssl.yaml | 2 +- overrides/compose.traefik.yaml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/overrides/compose.https.yaml b/overrides/compose.https.yaml index 66ca8d06..536ef276 100644 --- a/overrides/compose.https.yaml +++ b/overrides/compose.https.yaml @@ -14,7 +14,7 @@ services: - --providers.docker=true - --providers.docker.exposedbydefault=false # Keep v2 rule syntax for now - # Ensure compatibility with existing labels (will be removed if v3 transistion is complete) + # Ensure compatibility with existing labels (will be removed if v3 transition is complete) - --core.defaultRuleSyntax=v2 - --entrypoints.web.address=:80 - --entrypoints.web.http.redirections.entrypoint.to=websecure diff --git a/overrides/compose.proxy.yaml b/overrides/compose.proxy.yaml index 39b36749..d757833e 100644 --- a/overrides/compose.proxy.yaml +++ b/overrides/compose.proxy.yaml @@ -12,7 +12,7 @@ services: - --providers.docker - --providers.docker.exposedbydefault=false # Keep v2 rule syntax for now - # Ensure compatibility with existing labels (will be removed if v3 transistion is complete) + # Ensure compatibility with existing labels (will be removed if v3 transition is complete) - --core.defaultRuleSyntax=v2 - --entrypoints.web.address=:80 ports: diff --git a/overrides/compose.traefik-ssl.yaml b/overrides/compose.traefik-ssl.yaml index 1c3a0ad2..11bb92f9 100644 --- a/overrides/compose.traefik-ssl.yaml +++ b/overrides/compose.traefik-ssl.yaml @@ -24,7 +24,7 @@ services: # Do not expose all Docker services, only the ones explicitly exposed - --providers.docker.exposedbydefault=false # Keep v2 rule syntax for now - # Ensure compatibility with existing labels (will be removed if v3 transistion is complete) + # Ensure compatibility with existing labels (will be removed if v3 transition is complete) - --core.defaultRuleSyntax=v2 # Create an entrypoint http listening on port 80 - --entrypoints.http.address=:80 diff --git a/overrides/compose.traefik.yaml b/overrides/compose.traefik.yaml index 1846597f..4c3b8a88 100644 --- a/overrides/compose.traefik.yaml +++ b/overrides/compose.traefik.yaml @@ -25,7 +25,7 @@ services: # Do not expose all Docker services, only the ones explicitly exposed - --providers.docker.exposedbydefault=false # Keep v2 rule syntax for now - # Ensure compatibility with existing labels (will be removed if v3 transistion is complete) + # Ensure compatibility with existing labels (will be removed if v3 transition is complete) - --core.defaultRuleSyntax=v2 # Create an entrypoint http listening on port 80 - --entrypoints.http.address=:80 From a1265baed67279cdcc0c6cecf7ac412aa71605b6 Mon Sep 17 00:00:00 2001 From: RocketQuack <202538874+Rocket-Quack@users.noreply.github.com> Date: Mon, 19 Jan 2026 19:07:33 +0100 Subject: [PATCH 097/279] chore: run pre-commit fixes --- docs/02-setup/04-env-variables.md | 4 ++-- overrides/compose.https.yaml | 2 +- overrides/compose.proxy.yaml | 2 +- overrides/compose.traefik-ssl.yaml | 2 +- overrides/compose.traefik.yaml | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/02-setup/04-env-variables.md b/docs/02-setup/04-env-variables.md index c49cdc50..d169d518 100644 --- a/docs/02-setup/04-env-variables.md +++ b/docs/02-setup/04-env-variables.md @@ -60,9 +60,9 @@ SITES=`mysite.example.com` SITES=`{any:.+}` ``` ->Note: `SITES` currently supplies the host list that goes into the `Host(...)` rules. Once the Traefik v3 transition is completed, the plan is to switch to `SITES_RULE` (full rule expression) and deprecate `SITES` to map the Traefik Rule Syntax. +> Note: `SITES` currently supplies the host list that goes into the `Host(...)` rules. Once the Traefik v3 transition is completed, the plan is to switch to `SITES_RULE` (full rule expression) and deprecate `SITES` to map the Traefik Rule Syntax. ->Currently the used syntax is pinned to v2 via `--core.defaultRuleSyntax=v2`). +> Currently the used syntax is pinned to v2 via `--core.defaultRuleSyntax=v2`). --- diff --git a/overrides/compose.https.yaml b/overrides/compose.https.yaml index 536ef276..8e70fdfa 100644 --- a/overrides/compose.https.yaml +++ b/overrides/compose.https.yaml @@ -13,7 +13,7 @@ services: command: - --providers.docker=true - --providers.docker.exposedbydefault=false - # Keep v2 rule syntax for now + # Keep v2 rule syntax for now # Ensure compatibility with existing labels (will be removed if v3 transition is complete) - --core.defaultRuleSyntax=v2 - --entrypoints.web.address=:80 diff --git a/overrides/compose.proxy.yaml b/overrides/compose.proxy.yaml index d757833e..6b668437 100644 --- a/overrides/compose.proxy.yaml +++ b/overrides/compose.proxy.yaml @@ -11,7 +11,7 @@ services: command: - --providers.docker - --providers.docker.exposedbydefault=false - # Keep v2 rule syntax for now + # Keep v2 rule syntax for now # Ensure compatibility with existing labels (will be removed if v3 transition is complete) - --core.defaultRuleSyntax=v2 - --entrypoints.web.address=:80 diff --git a/overrides/compose.traefik-ssl.yaml b/overrides/compose.traefik-ssl.yaml index 11bb92f9..2770ce5b 100644 --- a/overrides/compose.traefik-ssl.yaml +++ b/overrides/compose.traefik-ssl.yaml @@ -23,7 +23,7 @@ services: - --providers.docker=true # Do not expose all Docker services, only the ones explicitly exposed - --providers.docker.exposedbydefault=false - # Keep v2 rule syntax for now + # Keep v2 rule syntax for now # Ensure compatibility with existing labels (will be removed if v3 transition is complete) - --core.defaultRuleSyntax=v2 # Create an entrypoint http listening on port 80 diff --git a/overrides/compose.traefik.yaml b/overrides/compose.traefik.yaml index 4c3b8a88..6e34acf4 100644 --- a/overrides/compose.traefik.yaml +++ b/overrides/compose.traefik.yaml @@ -24,7 +24,7 @@ services: - --providers.docker=true # Do not expose all Docker services, only the ones explicitly exposed - --providers.docker.exposedbydefault=false - # Keep v2 rule syntax for now + # Keep v2 rule syntax for now # Ensure compatibility with existing labels (will be removed if v3 transition is complete) - --core.defaultRuleSyntax=v2 # Create an entrypoint http listening on port 80 From 80a11fb47f1da37bbe2b9ddd156ae632792dda83 Mon Sep 17 00:00:00 2001 From: RocketQuack <202538874+Rocket-Quack@users.noreply.github.com> Date: Mon, 19 Jan 2026 19:31:55 +0100 Subject: [PATCH 098/279] chore: run pre-commit fixes --- docs/02-setup/04-env-variables.md | 8 +- docs/02-setup/05-overrides.md | 36 ++++---- docs/06-migration/02-traefik-v3-migration.md | 18 ++-- overrides/compose.https.yaml | 54 ++++++------ overrides/compose.proxy.yaml | 30 +++---- overrides/compose.traefik-ssl.yaml | 90 ++++++++++---------- overrides/compose.traefik.yaml | 80 ++++++++--------- 7 files changed, 161 insertions(+), 155 deletions(-) diff --git a/docs/02-setup/04-env-variables.md b/docs/02-setup/04-env-variables.md index c566ecd9..22a25790 100644 --- a/docs/02-setup/04-env-variables.md +++ b/docs/02-setup/04-env-variables.md @@ -45,10 +45,10 @@ Then edit `.env` and set variables according to your needs. ## HTTPS & SSL Configuration -| Variable | Purpose | Default | When to Set | -| ------------------- | ------------------------------------------------ | ------- | ---------------------------------------- | -| `LETSENCRYPT_EMAIL` | Email for Let's Encrypt certificate registration | β€” | Required if using HTTPS override | -| `SITES_RULE` | List of domains for SSL (Traefik rule for TLS domain routing) | β€” | Required if using reverse proxy override | +| Variable | Purpose | Default | When to Set | +| ------------------- | ------------------------------------------------------------- | ------- | ---------------------------------------- | +| `LETSENCRYPT_EMAIL` | Email for Let's Encrypt certificate registration | β€” | Required if using HTTPS override | +| `SITES_RULE` | List of domains for SSL (Traefik rule for TLS domain routing) | β€” | Required if using reverse proxy override | **Format for `SITES_RULE`:** diff --git a/docs/02-setup/05-overrides.md b/docs/02-setup/05-overrides.md index 156a6834..f1e274b1 100644 --- a/docs/02-setup/05-overrides.md +++ b/docs/02-setup/05-overrides.md @@ -4,24 +4,24 @@ Overrides extend the base compose.yaml with additional services or modify existi docker compose -f compose.yaml -f overrides/compose.mariadb.yaml -f overrides/compose.redis.yaml config > compose.custom.yaml ``` -| Overrider | Purpose | Additional Info | -| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | -| **Database** | | | -| compose.mariadb.yaml | Adds MariaDB database service | set `DB_PASSWORD` or default Password will be used | -| compose.mariadb-secrets.yaml | Adds MariaDB with password from a secret file instead of environment variable | Set `DB_PASSWORD_SECRETS_FILE` to the path of your secret file | -| compose.mariadb-shared.yaml | Makes MariaDB available on a shared network (mariadb-network) for other services | set `DB_PASSWORD` | -| compose.postgres.yaml | Uses PostgreSQL instead of MariaDB as the database | set `DB_PASSWORD` | -| **Proxy** | | | -| compose.noproxy.yaml | Exposes the application directly on port `:8080` without a reverse proxy | | -| compose.proxy.yaml | Uses Traefik as HTTP reverse proxy on port `:80` | You can change the published port by setting `HTTP_PUBLISH_PORT` | +| Overrider | Purpose | Additional Info | +| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | +| **Database** | | | +| compose.mariadb.yaml | Adds MariaDB database service | set `DB_PASSWORD` or default Password will be used | +| compose.mariadb-secrets.yaml | Adds MariaDB with password from a secret file instead of environment variable | Set `DB_PASSWORD_SECRETS_FILE` to the path of your secret file | +| compose.mariadb-shared.yaml | Makes MariaDB available on a shared network (mariadb-network) for other services | set `DB_PASSWORD` | +| compose.postgres.yaml | Uses PostgreSQL instead of MariaDB as the database | set `DB_PASSWORD` | +| **Proxy** | | | +| compose.noproxy.yaml | Exposes the application directly on port `:8080` without a reverse proxy | | +| compose.proxy.yaml | Uses Traefik as HTTP reverse proxy on port `:80` | You can change the published port by setting `HTTP_PUBLISH_PORT` | | compose.https.yaml | Uses Traefik as HTTPS reverse proxy on Port `:443` with automatic HTTP-to-HTTPS redirect | `SITES_RULE` and `LETSENCRYPT_EMAIL` must be set. `HTTP_PUBLISH_PORT` and `HTTPS_PUBLISH_PORT` can be set. | -| **Redis** | | | +| **Redis** | | | | compose.redis.yaml | Adds Redis service for caching and background job queuing | | **TBD** | **The following overrides are available but lack documentation. If you use them and understand their purpose, please consider contributing to this documentation.** | -| compose.backup-cron.yaml | | | -| compose.custom-domain-ssl.yaml | | | -| compose.custom-domain.yaml | | | -| compose.multi-bench-ssl.yaml | | | -| compose.multi-bench.yaml | | | -| compose.traefik-ssl.yaml | | | -| compose.traefik.yaml | | | +| compose.backup-cron.yaml | | | +| compose.custom-domain-ssl.yaml | | | +| compose.custom-domain.yaml | | | +| compose.multi-bench-ssl.yaml | | | +| compose.multi-bench.yaml | | | +| compose.traefik-ssl.yaml | | | +| compose.traefik.yaml | | | diff --git a/docs/06-migration/02-traefik-v3-migration.md b/docs/06-migration/02-traefik-v3-migration.md index 9e4ed21f..b452779c 100644 --- a/docs/06-migration/02-traefik-v3-migration.md +++ b/docs/06-migration/02-traefik-v3-migration.md @@ -3,24 +3,27 @@ Use this guide if you already run Traefik v2 with `frappe_docker` and want to upgrade to v3. It focuses on the image upgrade and the v3 routing rule changes that affect existing setups. ### Before you start + Before migrating anything, it is always recommended to create a backup. Better safe than sorry. In particular, compose and .env should be backed up. ### Quick upgrade summary -1) Pull the updated repo -2) Update env variables especially the updated `SITES` to `SITES_RULE` -3) Regenerate the compose config and restart the stack +1. Pull the updated repo +2. Update env variables especially the updated `SITES` to `SITES_RULE` +3. Regenerate the compose config and restart the stack #### Multiple hostnames v2 allowed comma-separated host lists inside `Host(...)`. In v3 traefik uses logical OR **Before (v2):** + ``` Host(`a.example.com`,`b.example.com`) ``` **After (v3):** + ``` Host(`a.example.com`) || Host(`b.example.com`) ``` @@ -30,11 +33,13 @@ Host(`a.example.com`) || Host(`b.example.com`) All Traefik routing for HTTPS and multi-bench setups now uses `SITES_RULE`, which is a full v3 rule expression **Single site:** + ``` SITES_RULE=Host(`erp.example.com`) ``` **Multiple sites:** + ``` SITES_RULE=Host(`a.example.com`) || Host(`b.example.com`) ``` @@ -51,6 +56,7 @@ docker compose --env-file .env \ -f overrides/compose.https.yaml \ config > ~/gitops/docker-compose.yml ``` + ```sh docker compose --project-name -f ~/gitops/docker-compose.yml up -d ``` @@ -65,6 +71,6 @@ After restarting, Traefik will be used in the new supported version 3.6 and the If you need to rollback: -1) Revert Traefik image to `v2.11` -2) Restore the old `SITES` variable format and v2 rules -3) Regenerate the compose config and restart +1. Revert Traefik image to `v2.11` +2. Restore the old `SITES` variable format and v2 rules +3. Regenerate the compose config and restart diff --git a/overrides/compose.https.yaml b/overrides/compose.https.yaml index 55b453e8..c9c0f525 100644 --- a/overrides/compose.https.yaml +++ b/overrides/compose.https.yaml @@ -1,33 +1,33 @@ -services: - frontend: - labels: +services: + frontend: + labels: - traefik.enable=true - traefik.http.services.frontend.loadbalancer.server.port=8080 - traefik.http.routers.frontend-http.entrypoints=websecure - traefik.http.routers.frontend-http.tls.certresolver=main-resolver - traefik.http.routers.frontend-http.ruleSyntax=v3 - traefik.http.routers.frontend-http.rule=${SITES_RULE:?SITES_RULE not set} - - proxy: - image: traefik:v3.6 - restart: unless-stopped - command: - - --providers.docker=true - - --providers.docker.exposedbydefault=false - - --entrypoints.web.address=:80 - - --entrypoints.web.http.redirections.entrypoint.to=websecure - - --entrypoints.web.http.redirections.entrypoint.scheme=https - - --entrypoints.websecure.address=:443 - - --certificatesResolvers.main-resolver.acme.httpChallenge=true - - --certificatesResolvers.main-resolver.acme.httpChallenge.entrypoint=web - - --certificatesResolvers.main-resolver.acme.email=${LETSENCRYPT_EMAIL:?No Let's Encrypt email set} - - --certificatesResolvers.main-resolver.acme.storage=/letsencrypt/acme.json - ports: - - ${HTTP_PUBLISH_PORT:-80}:80 - - ${HTTPS_PUBLISH_PORT:-443}:443 - volumes: - - cert-data:/letsencrypt - - /var/run/docker.sock:/var/run/docker.sock:ro - -volumes: - cert-data: + + proxy: + image: traefik:v3.6 + restart: unless-stopped + command: + - --providers.docker=true + - --providers.docker.exposedbydefault=false + - --entrypoints.web.address=:80 + - --entrypoints.web.http.redirections.entrypoint.to=websecure + - --entrypoints.web.http.redirections.entrypoint.scheme=https + - --entrypoints.websecure.address=:443 + - --certificatesResolvers.main-resolver.acme.httpChallenge=true + - --certificatesResolvers.main-resolver.acme.httpChallenge.entrypoint=web + - --certificatesResolvers.main-resolver.acme.email=${LETSENCRYPT_EMAIL:?No Let's Encrypt email set} + - --certificatesResolvers.main-resolver.acme.storage=/letsencrypt/acme.json + ports: + - ${HTTP_PUBLISH_PORT:-80}:80 + - ${HTTPS_PUBLISH_PORT:-443}:443 + volumes: + - cert-data:/letsencrypt + - /var/run/docker.sock:/var/run/docker.sock:ro + +volumes: + cert-data: diff --git a/overrides/compose.proxy.yaml b/overrides/compose.proxy.yaml index b3c467c7..feada975 100644 --- a/overrides/compose.proxy.yaml +++ b/overrides/compose.proxy.yaml @@ -1,20 +1,20 @@ -services: - frontend: - labels: +services: + frontend: + labels: - traefik.enable=true - traefik.http.services.frontend.loadbalancer.server.port=8080 - traefik.http.routers.frontend-http.entrypoints=web - traefik.http.routers.frontend-http.ruleSyntax=v3 - traefik.http.routers.frontend-http.rule=HostRegexp(`^.+$`) - - proxy: - image: traefik:v3.6 - command: - - --providers.docker - - --providers.docker.exposedbydefault=false - - --entrypoints.web.address=:80 - ports: - - ${HTTP_PUBLISH_PORT:-80}:80 - volumes: - - /var/run/docker.sock:/var/run/docker.sock:ro - userns_mode: host + + proxy: + image: traefik:v3.6 + command: + - --providers.docker + - --providers.docker.exposedbydefault=false + - --entrypoints.web.address=:80 + ports: + - ${HTTP_PUBLISH_PORT:-80}:80 + volumes: + - /var/run/docker.sock:/var/run/docker.sock:ro + userns_mode: host diff --git a/overrides/compose.traefik-ssl.yaml b/overrides/compose.traefik-ssl.yaml index 19083bf2..0bdf45fe 100644 --- a/overrides/compose.traefik-ssl.yaml +++ b/overrides/compose.traefik-ssl.yaml @@ -1,49 +1,49 @@ -services: - traefik: - labels: - # https-redirect middleware to redirect HTTP to HTTPS - # It can be reused by other stacks in other Docker Compose files - - traefik.http.middlewares.https-redirect.redirectscheme.scheme=https - - traefik.http.middlewares.https-redirect.redirectscheme.permanent=true - # traefik-http to use the middleware to redirect to https - - traefik.http.routers.traefik-public-http.middlewares=https-redirect +services: + traefik: + labels: + # https-redirect middleware to redirect HTTP to HTTPS + # It can be reused by other stacks in other Docker Compose files + - traefik.http.middlewares.https-redirect.redirectscheme.scheme=https + - traefik.http.middlewares.https-redirect.redirectscheme.permanent=true + # traefik-http to use the middleware to redirect to https + - traefik.http.routers.traefik-public-http.middlewares=https-redirect # traefik-https the actual router using HTTPS # Uses the environment variable DOMAIN - traefik.http.routers.traefik-public-https.ruleSyntax=v3 - traefik.http.routers.traefik-public-https.rule=Host(`${TRAEFIK_DOMAIN}`) - - traefik.http.routers.traefik-public-https.entrypoints=https - - traefik.http.routers.traefik-public-https.tls=true - # Use the special Traefik service api@internal with the web UI/Dashboard - - traefik.http.routers.traefik-public-https.service=api@internal - # Use the "le" (Let's Encrypt) resolver created below - - traefik.http.routers.traefik-public-https.tls.certresolver=le - # Enable HTTP Basic auth, using the middleware created above - - traefik.http.routers.traefik-public-https.middlewares=admin-auth - command: - # Enable Docker in Traefik, so that it reads labels from Docker services - - --providers.docker=true - # Do not expose all Docker services, only the ones explicitly exposed - - --providers.docker.exposedbydefault=false - # Create an entrypoint http listening on port 80 - - --entrypoints.http.address=:80 - # Create an entrypoint https listening on port 443 - - --entrypoints.https.address=:443 - # Create the certificate resolver le for Let's Encrypt, uses the environment variable EMAIL - - --certificatesresolvers.le.acme.email=${EMAIL:?No EMAIL set} - # Store the Let's Encrypt certificates in the mounted volume - - --certificatesresolvers.le.acme.storage=/certificates/acme.json - # Use the TLS Challenge for Let's Encrypt - - --certificatesresolvers.le.acme.tlschallenge=true - # Enable the access log, with HTTP requests - - --accesslog - # Enable the Traefik log, for configurations and errors - - --log - # Enable the Dashboard and API - - --api - ports: - - ${HTTPS_PUBLISH_PORT:-443}:443 - volumes: - - cert-data:/certificates - -volumes: - cert-data: + - traefik.http.routers.traefik-public-https.entrypoints=https + - traefik.http.routers.traefik-public-https.tls=true + # Use the special Traefik service api@internal with the web UI/Dashboard + - traefik.http.routers.traefik-public-https.service=api@internal + # Use the "le" (Let's Encrypt) resolver created below + - traefik.http.routers.traefik-public-https.tls.certresolver=le + # Enable HTTP Basic auth, using the middleware created above + - traefik.http.routers.traefik-public-https.middlewares=admin-auth + command: + # Enable Docker in Traefik, so that it reads labels from Docker services + - --providers.docker=true + # Do not expose all Docker services, only the ones explicitly exposed + - --providers.docker.exposedbydefault=false + # Create an entrypoint http listening on port 80 + - --entrypoints.http.address=:80 + # Create an entrypoint https listening on port 443 + - --entrypoints.https.address=:443 + # Create the certificate resolver le for Let's Encrypt, uses the environment variable EMAIL + - --certificatesresolvers.le.acme.email=${EMAIL:?No EMAIL set} + # Store the Let's Encrypt certificates in the mounted volume + - --certificatesresolvers.le.acme.storage=/certificates/acme.json + # Use the TLS Challenge for Let's Encrypt + - --certificatesresolvers.le.acme.tlschallenge=true + # Enable the access log, with HTTP requests + - --accesslog + # Enable the Traefik log, for configurations and errors + - --log + # Enable the Dashboard and API + - --api + ports: + - ${HTTPS_PUBLISH_PORT:-443}:443 + volumes: + - cert-data:/certificates + +volumes: + cert-data: diff --git a/overrides/compose.traefik.yaml b/overrides/compose.traefik.yaml index 01ad3c5f..15885363 100644 --- a/overrides/compose.traefik.yaml +++ b/overrides/compose.traefik.yaml @@ -1,46 +1,46 @@ -services: - traefik: - image: "traefik:v3.6" - restart: unless-stopped - labels: - # Enable Traefik for this service, to make it available in the public network - - traefik.enable=true - # Use the traefik-public network (declared below) - - traefik.docker.network=traefik-public +services: + traefik: + image: "traefik:v3.6" + restart: unless-stopped + labels: + # Enable Traefik for this service, to make it available in the public network + - traefik.enable=true + # Use the traefik-public network (declared below) + - traefik.docker.network=traefik-public # admin-auth middleware with HTTP Basic auth # Using the environment variables USERNAME and HASHED_PASSWORD - traefik.http.middlewares.admin-auth.basicauth.users=admin:${HASHED_PASSWORD:?No HASHED_PASSWORD set} # Uses the environment variable TRAEFIK_DOMAIN - traefik.http.routers.traefik-public-http.ruleSyntax=v3 - traefik.http.routers.traefik-public-http.rule=Host(`${TRAEFIK_DOMAIN:?No TRAEFIK_DOMAIN set}`) - - traefik.http.routers.traefik-public-http.entrypoints=http - # Use the special Traefik service api@internal with the web UI/Dashboard - - traefik.http.routers.traefik-public-http.service=api@internal - # Enable HTTP Basic auth, using the middleware created above - - traefik.http.routers.traefik-public-http.middlewares=admin-auth - # Define the port inside of the Docker service to use - - traefik.http.services.traefik-public.loadbalancer.server.port=8080 - command: - # Enable Docker in Traefik, so that it reads labels from Docker services - - --providers.docker=true - # Do not expose all Docker services, only the ones explicitly exposed - - --providers.docker.exposedbydefault=false - # Create an entrypoint http listening on port 80 - - --entrypoints.http.address=:80 - # Enable the access log, with HTTP requests - - --accesslog - # Enable the Traefik log, for configurations and errors - - --log - # Enable the Dashboard and API - - --api - ports: - - ${HTTP_PUBLISH_PORT:-80}:80 - volumes: - - /var/run/docker.sock:/var/run/docker.sock:ro - networks: - - traefik-public - -networks: - traefik-public: - name: traefik-public - external: false + - traefik.http.routers.traefik-public-http.entrypoints=http + # Use the special Traefik service api@internal with the web UI/Dashboard + - traefik.http.routers.traefik-public-http.service=api@internal + # Enable HTTP Basic auth, using the middleware created above + - traefik.http.routers.traefik-public-http.middlewares=admin-auth + # Define the port inside of the Docker service to use + - traefik.http.services.traefik-public.loadbalancer.server.port=8080 + command: + # Enable Docker in Traefik, so that it reads labels from Docker services + - --providers.docker=true + # Do not expose all Docker services, only the ones explicitly exposed + - --providers.docker.exposedbydefault=false + # Create an entrypoint http listening on port 80 + - --entrypoints.http.address=:80 + # Enable the access log, with HTTP requests + - --accesslog + # Enable the Traefik log, for configurations and errors + - --log + # Enable the Dashboard and API + - --api + ports: + - ${HTTP_PUBLISH_PORT:-80}:80 + volumes: + - /var/run/docker.sock:/var/run/docker.sock:ro + networks: + - traefik-public + +networks: + traefik-public: + name: traefik-public + external: false From a69b002881758e906a60cd362c64b1be17e93035 Mon Sep 17 00:00:00 2001 From: RocketQuack <202538874+Rocket-Quack@users.noreply.github.com> Date: Tue, 20 Jan 2026 13:23:30 +0100 Subject: [PATCH 099/279] tests: set SITES_RULE correctly for https override --- tests/conftest.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/conftest.py b/tests/conftest.py index c6ff166a..24c9f750 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -26,11 +26,19 @@ def _add_version_var(name: str, env_path: Path): def _add_sites_var(env_path: Path): with open(env_path, "r+") as f: content = f.read() + sites = ( + "tests.localhost", + "test-erpnext-site.localhost", + "test-pg-site.localhost", + ) + sites_list = ",".join(f"`{site}`" for site in sites) + sites_rule = " || ".join(f"Host(`{site}`)" for site in sites) content = re.sub( rf"SITES=.*", - f"SITES=`tests.localhost`,`test-erpnext-site.localhost`,`test-pg-site.localhost`", + f"SITES={sites_list}", content, ) + content = re.sub(rf"SITES_RULE=.*", f"SITES_RULE={sites_rule}", content) f.seek(0) f.truncate() f.write(content) From 56c8f7e2775db621300f7d4484843ff3e8cfb047 Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 20 Jan 2026 17:03:43 +0000 Subject: [PATCH 100/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 5d58a451..b3411195 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v15.94.3 +ERPNEXT_VERSION=v15.95.0 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index e2ca0344..934be06e 100644 --- a/pwd.yml +++ b/pwd.yml @@ -1,6 +1,6 @@ services: backend: - image: frappe/erpnext:v15.94.3 + image: frappe/erpnext:v15.95.0 networks: - frappe_network deploy: @@ -16,7 +16,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v15.94.3 + image: frappe/erpnext:v15.95.0 networks: - frappe_network deploy: @@ -45,7 +45,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v15.94.3 + image: frappe/erpnext:v15.95.0 networks: - frappe_network deploy: @@ -100,7 +100,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v15.94.3 + image: frappe/erpnext:v15.95.0 networks: - frappe_network depends_on: @@ -126,7 +126,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v15.94.3 + image: frappe/erpnext:v15.95.0 networks: - frappe_network deploy: @@ -145,7 +145,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v15.94.3 + image: frappe/erpnext:v15.95.0 networks: - frappe_network deploy: @@ -182,7 +182,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v15.94.3 + image: frappe/erpnext:v15.95.0 networks: - frappe_network deploy: @@ -196,7 +196,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v15.94.3 + image: frappe/erpnext:v15.95.0 networks: - frappe_network deploy: From 269e44e2cdb91338a79672e38d001fd673912870 Mon Sep 17 00:00:00 2001 From: RocketQuack <202538874+Rocket-Quack@users.noreply.github.com> Date: Sun, 25 Jan 2026 14:30:48 +0100 Subject: [PATCH 101/279] feat: drop rule syntax and v2 override --- overrides/compose.custom-domain.yaml | 1 - overrides/compose.https.yaml | 4 ---- overrides/compose.multi-bench-ssl.yaml | 1 - overrides/compose.multi-bench.yaml | 1 - overrides/compose.proxy.yaml | 4 ---- overrides/compose.traefik-ssl.yaml | 4 ---- overrides/compose.traefik.yaml | 4 ---- 7 files changed, 19 deletions(-) diff --git a/overrides/compose.custom-domain.yaml b/overrides/compose.custom-domain.yaml index 7ca31776..ca1b54f7 100644 --- a/overrides/compose.custom-domain.yaml +++ b/overrides/compose.custom-domain.yaml @@ -14,7 +14,6 @@ services: - traefik.http.services.${ROUTER?ROUTER not set}.loadbalancer.server.port=2016 - traefik.http.routers.${ROUTER}.service=${ROUTER} - traefik.http.routers.${ROUTER}.entrypoints=http - - traefik.http.routers.${ROUTER}.ruleSyntax=v3 - traefik.http.routers.${ROUTER}.rule=${SITES_RULE?SITES_RULE not set} - traefik.http.middlewares.${ROUTER}.headers.customrequestheaders.Host=${BASE_SITE?BASE_SITE not set} - traefik.http.routers.${ROUTER}.middlewares=${ROUTER} diff --git a/overrides/compose.https.yaml b/overrides/compose.https.yaml index 13555363..32ef2bae 100644 --- a/overrides/compose.https.yaml +++ b/overrides/compose.https.yaml @@ -5,7 +5,6 @@ services: - traefik.http.services.frontend.loadbalancer.server.port=8080 - traefik.http.routers.frontend-http.entrypoints=websecure - traefik.http.routers.frontend-http.tls.certresolver=main-resolver - - traefik.http.routers.frontend-http.ruleSyntax=v3 - traefik.http.routers.frontend-http.rule=${SITES_RULE:?SITES_RULE not set} proxy: @@ -14,9 +13,6 @@ services: command: - --providers.docker=true - --providers.docker.exposedbydefault=false - # Keep v2 rule syntax for now - # Ensure compatibility with existing labels (will be removed if v3 transition is complete) - - --core.defaultRuleSyntax=v2 - --entrypoints.web.address=:80 - --entrypoints.web.http.redirections.entrypoint.to=websecure - --entrypoints.web.http.redirections.entrypoint.scheme=https diff --git a/overrides/compose.multi-bench-ssl.yaml b/overrides/compose.multi-bench-ssl.yaml index e38da19b..1c5e3dac 100644 --- a/overrides/compose.multi-bench-ssl.yaml +++ b/overrides/compose.multi-bench-ssl.yaml @@ -5,7 +5,6 @@ services: - traefik.http.routers.${ROUTER}-http.middlewares=https-redirect # ${ROUTER}-https the actual router using HTTPS # Uses the environment variable SITES_RULE - - traefik.http.routers.${ROUTER}-https.ruleSyntax=v3 - traefik.http.routers.${ROUTER}-https.rule=${SITES_RULE?SITES_RULE not set} - traefik.http.routers.${ROUTER}-https.entrypoints=https - traefik.http.routers.${ROUTER}-https.tls=true diff --git a/overrides/compose.multi-bench.yaml b/overrides/compose.multi-bench.yaml index 542e7716..d499686b 100644 --- a/overrides/compose.multi-bench.yaml +++ b/overrides/compose.multi-bench.yaml @@ -9,7 +9,6 @@ services: - traefik.http.services.${ROUTER?ROUTER not set}.loadbalancer.server.port=8080 - traefik.http.routers.${ROUTER}-http.service=${ROUTER} - traefik.http.routers.${ROUTER}-http.entrypoints=http - - traefik.http.routers.${ROUTER}-http.ruleSyntax=v3 - traefik.http.routers.${ROUTER}-http.rule=${SITES_RULE?SITES_RULE not set} configurator: networks: diff --git a/overrides/compose.proxy.yaml b/overrides/compose.proxy.yaml index a47b3a7e..4b084eaa 100644 --- a/overrides/compose.proxy.yaml +++ b/overrides/compose.proxy.yaml @@ -4,7 +4,6 @@ services: - traefik.enable=true - traefik.http.services.frontend.loadbalancer.server.port=8080 - traefik.http.routers.frontend-http.entrypoints=web - - traefik.http.routers.frontend-http.ruleSyntax=v3 - traefik.http.routers.frontend-http.rule=HostRegexp(`^.+$`) proxy: @@ -12,9 +11,6 @@ services: command: - --providers.docker - --providers.docker.exposedbydefault=false - # Keep v2 rule syntax for now - # Ensure compatibility with existing labels (will be removed if v3 transition is complete) - - --core.defaultRuleSyntax=v2 - --entrypoints.web.address=:80 ports: - ${HTTP_PUBLISH_PORT:-80}:80 diff --git a/overrides/compose.traefik-ssl.yaml b/overrides/compose.traefik-ssl.yaml index 2563363c..b83cb8e4 100644 --- a/overrides/compose.traefik-ssl.yaml +++ b/overrides/compose.traefik-ssl.yaml @@ -9,7 +9,6 @@ services: - traefik.http.routers.traefik-public-http.middlewares=https-redirect # traefik-https the actual router using HTTPS # Uses the environment variable DOMAIN - - traefik.http.routers.traefik-public-https.ruleSyntax=v3 - traefik.http.routers.traefik-public-https.rule=Host(`${TRAEFIK_DOMAIN}`) - traefik.http.routers.traefik-public-https.entrypoints=https - traefik.http.routers.traefik-public-https.tls=true @@ -24,9 +23,6 @@ services: - --providers.docker=true # Do not expose all Docker services, only the ones explicitly exposed - --providers.docker.exposedbydefault=false - # Keep v2 rule syntax for now - # Ensure compatibility with existing labels (will be removed if v3 transition is complete) - - --core.defaultRuleSyntax=v2 # Create an entrypoint http listening on port 80 - --entrypoints.http.address=:80 # Create an entrypoint https listening on port 443 diff --git a/overrides/compose.traefik.yaml b/overrides/compose.traefik.yaml index e36fcd2b..3dd2069f 100644 --- a/overrides/compose.traefik.yaml +++ b/overrides/compose.traefik.yaml @@ -11,7 +11,6 @@ services: # Using the environment variables USERNAME and HASHED_PASSWORD - traefik.http.middlewares.admin-auth.basicauth.users=admin:${HASHED_PASSWORD:?No HASHED_PASSWORD set} # Uses the environment variable TRAEFIK_DOMAIN - - traefik.http.routers.traefik-public-http.ruleSyntax=v3 - traefik.http.routers.traefik-public-http.rule=Host(`${TRAEFIK_DOMAIN:?No TRAEFIK_DOMAIN set}`) - traefik.http.routers.traefik-public-http.entrypoints=http # Use the special Traefik service api@internal with the web UI/Dashboard @@ -25,9 +24,6 @@ services: - --providers.docker=true # Do not expose all Docker services, only the ones explicitly exposed - --providers.docker.exposedbydefault=false - # Keep v2 rule syntax for now - # Ensure compatibility with existing labels (will be removed if v3 transition is complete) - - --core.defaultRuleSyntax=v2 # Create an entrypoint http listening on port 80 - --entrypoints.http.address=:80 # Enable the access log, with HTTP requests From bfb040e5a6c348bf4c563f8263ac540091a5a263 Mon Sep 17 00:00:00 2001 From: RocketQuack <202538874+Rocket-Quack@users.noreply.github.com> Date: Sun, 25 Jan 2026 14:31:46 +0100 Subject: [PATCH 102/279] docs: mark v3 migration complete --- docs/02-setup/04-env-variables.md | 5 ++--- docs/06-migration/02-traefik-v3-migration.md | 7 +++++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/02-setup/04-env-variables.md b/docs/02-setup/04-env-variables.md index 29aa94ec..a9c73a8a 100644 --- a/docs/02-setup/04-env-variables.md +++ b/docs/02-setup/04-env-variables.md @@ -60,9 +60,8 @@ SITES_RULE=Host(`mysite.example.com`) SITES_RULE=Host(`a.example.com`) || Host(`b.example.com`) ``` -> Note: `SITES` currently supplies the host list that goes into the `Host(...)` rules. Once the Traefik v3 transition is completed, the plan is to switch to `SITES_RULE` (full rule expression) and deprecate `SITES` to map the Traefik Rule Syntax. - -> Currently the used syntax is pinned to v2 via `--core.defaultRuleSyntax=v2`). +> Note: The Traefik v3 migration is complete. Use `SITES_RULE` as a full v3 rule expression; `SITES` is deprecated. +> Rule syntax now defaults to v3, so no `core.defaultRuleSyntax` or per-router `ruleSyntax` settings are required. --- diff --git a/docs/06-migration/02-traefik-v3-migration.md b/docs/06-migration/02-traefik-v3-migration.md index b452779c..cb0eee11 100644 --- a/docs/06-migration/02-traefik-v3-migration.md +++ b/docs/06-migration/02-traefik-v3-migration.md @@ -2,6 +2,9 @@ Use this guide if you already run Traefik v2 with `frappe_docker` and want to upgrade to v3. It focuses on the image upgrade and the v3 routing rule changes that affect existing setups. +> Note: The Traefik v2 -> v3 migration is complete. The provided overrides no longer set `core.defaultRuleSyntax` or per-router `ruleSyntax` labels, because v3 is the default rule syntax. +> Note: If you have a system that must continue to run on v2 despite EOL, you can pin v2 rule syntax with `--core.defaultRuleSyntax=v2` in your Traefik service. + ### Before you start Before migrating anything, it is always recommended to create a backup. Better safe than sorry. In particular, compose and .env should be backed up. @@ -14,7 +17,7 @@ Before migrating anything, it is always recommended to create a backup. Better s #### Multiple hostnames -v2 allowed comma-separated host lists inside `Host(...)`. In v3 traefik uses logical OR +v2 allowed comma-separated host lists inside `Host(...)`. In v3 Traefik uses logical OR. **Before (v2):** @@ -30,7 +33,7 @@ Host(`a.example.com`) || Host(`b.example.com`) ### Step 1: Replace `SITES` with `SITES_RULE` -All Traefik routing for HTTPS and multi-bench setups now uses `SITES_RULE`, which is a full v3 rule expression +All Traefik routing for HTTPS and multi-bench setups now uses `SITES_RULE`, which is a full v3 rule expression. **Single site:** From a022f94591642ceb6a9b6aef4e15122724edc83d Mon Sep 17 00:00:00 2001 From: RocketQuack <202538874+Rocket-Quack@users.noreply.github.com> Date: Sun, 25 Jan 2026 14:33:02 +0100 Subject: [PATCH 103/279] tests: stop writing legacy SITES in env --- tests/conftest.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 24c9f750..63169e37 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -31,13 +31,7 @@ def _add_sites_var(env_path: Path): "test-erpnext-site.localhost", "test-pg-site.localhost", ) - sites_list = ",".join(f"`{site}`" for site in sites) sites_rule = " || ".join(f"Host(`{site}`)" for site in sites) - content = re.sub( - rf"SITES=.*", - f"SITES={sites_list}", - content, - ) content = re.sub(rf"SITES_RULE=.*", f"SITES_RULE={sites_rule}", content) f.seek(0) f.truncate() From 9a429695a8670c42291236f05840f1da422e4b13 Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 28 Jan 2026 04:39:33 +0000 Subject: [PATCH 104/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 7730bf63..1726c878 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v15.95.0 +ERPNEXT_VERSION=v15.95.1 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index 934be06e..049a47e0 100644 --- a/pwd.yml +++ b/pwd.yml @@ -1,6 +1,6 @@ services: backend: - image: frappe/erpnext:v15.95.0 + image: frappe/erpnext:v15.95.1 networks: - frappe_network deploy: @@ -16,7 +16,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v15.95.0 + image: frappe/erpnext:v15.95.1 networks: - frappe_network deploy: @@ -45,7 +45,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v15.95.0 + image: frappe/erpnext:v15.95.1 networks: - frappe_network deploy: @@ -100,7 +100,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v15.95.0 + image: frappe/erpnext:v15.95.1 networks: - frappe_network depends_on: @@ -126,7 +126,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v15.95.0 + image: frappe/erpnext:v15.95.1 networks: - frappe_network deploy: @@ -145,7 +145,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v15.95.0 + image: frappe/erpnext:v15.95.1 networks: - frappe_network deploy: @@ -182,7 +182,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v15.95.0 + image: frappe/erpnext:v15.95.1 networks: - frappe_network deploy: @@ -196,7 +196,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v15.95.0 + image: frappe/erpnext:v15.95.1 networks: - frappe_network deploy: From 23593bfadb0ceb949961e2b26242b77029d2563b Mon Sep 17 00:00:00 2001 From: github-actions Date: Thu, 29 Jan 2026 13:24:18 +0000 Subject: [PATCH 105/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 1726c878..9ad64a1d 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v15.95.1 +ERPNEXT_VERSION=v15.95.2 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index 049a47e0..0d06f6ad 100644 --- a/pwd.yml +++ b/pwd.yml @@ -1,6 +1,6 @@ services: backend: - image: frappe/erpnext:v15.95.1 + image: frappe/erpnext:v15.95.2 networks: - frappe_network deploy: @@ -16,7 +16,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v15.95.1 + image: frappe/erpnext:v15.95.2 networks: - frappe_network deploy: @@ -45,7 +45,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v15.95.1 + image: frappe/erpnext:v15.95.2 networks: - frappe_network deploy: @@ -100,7 +100,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v15.95.1 + image: frappe/erpnext:v15.95.2 networks: - frappe_network depends_on: @@ -126,7 +126,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v15.95.1 + image: frappe/erpnext:v15.95.2 networks: - frappe_network deploy: @@ -145,7 +145,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v15.95.1 + image: frappe/erpnext:v15.95.2 networks: - frappe_network deploy: @@ -182,7 +182,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v15.95.1 + image: frappe/erpnext:v15.95.2 networks: - frappe_network deploy: @@ -196,7 +196,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v15.95.1 + image: frappe/erpnext:v15.95.2 networks: - frappe_network deploy: From 30efa35347984de3898382beacf2db53de25a61c Mon Sep 17 00:00:00 2001 From: david-loe <56305409+david-loe@users.noreply.github.com> Date: Fri, 30 Jan 2026 16:48:12 +0100 Subject: [PATCH 106/279] Update Python and Node.js versions in Containerfile --- images/custom/Containerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/images/custom/Containerfile b/images/custom/Containerfile index 06182d42..ebe7eccb 100644 --- a/images/custom/Containerfile +++ b/images/custom/Containerfile @@ -1,4 +1,4 @@ -ARG PYTHON_VERSION=3.11.6 +ARG PYTHON_VERSION=3.14.2 ARG DEBIAN_BASE=bookworm FROM python:${PYTHON_VERSION}-slim-${DEBIAN_BASE} AS base @@ -7,7 +7,7 @@ COPY resources/nginx-entrypoint.sh /usr/local/bin/nginx-entrypoint.sh ARG WKHTMLTOPDF_VERSION=0.12.6.1-3 ARG WKHTMLTOPDF_DISTRO=bookworm -ARG NODE_VERSION=20.19.2 +ARG NODE_VERSION=24.13.0 ENV NVM_DIR=/home/frappe/.nvm ENV PATH=${NVM_DIR}/versions/node/v${NODE_VERSION}/bin/:${PATH} From fbf00c802d19470156720c677ee37b80dbe6f2b6 Mon Sep 17 00:00:00 2001 From: david-loe <56305409+david-loe@users.noreply.github.com> Date: Sat, 31 Jan 2026 09:06:00 +0100 Subject: [PATCH 107/279] Update Python, Node, and Frappe versions in Containerfile --- images/production/Containerfile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/images/production/Containerfile b/images/production/Containerfile index 563bc763..42f41939 100644 --- a/images/production/Containerfile +++ b/images/production/Containerfile @@ -1,10 +1,10 @@ -ARG PYTHON_VERSION=3.11.6 +ARG PYTHON_VERSION=3.14.2 ARG DEBIAN_BASE=bookworm FROM python:${PYTHON_VERSION}-slim-${DEBIAN_BASE} AS base ARG WKHTMLTOPDF_VERSION=0.12.6.1-3 ARG WKHTMLTOPDF_DISTRO=bookworm -ARG NODE_VERSION=20.19.2 +ARG NODE_VERSION=24.13.0 ENV NVM_DIR=/home/frappe/.nvm ENV PATH=${NVM_DIR}/versions/node/v${NODE_VERSION}/bin/:${PATH} @@ -103,10 +103,10 @@ USER frappe FROM build AS builder -ARG FRAPPE_BRANCH=version-15 +ARG FRAPPE_BRANCH=version-16 ARG FRAPPE_PATH=https://github.com/frappe/frappe ARG ERPNEXT_REPO=https://github.com/frappe/erpnext -ARG ERPNEXT_BRANCH=version-15 +ARG ERPNEXT_BRANCH=version-16 RUN bench init \ --frappe-branch=${FRAPPE_BRANCH} \ --frappe-path=${FRAPPE_PATH} \ From 4a29d63c52b88517bd83e7940466a2771c91744d Mon Sep 17 00:00:00 2001 From: david-loe <56305409+david-loe@users.noreply.github.com> Date: Sat, 31 Jan 2026 09:08:17 +0100 Subject: [PATCH 108/279] Update Frappe branch version to 16 --- images/layered/Containerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/images/layered/Containerfile b/images/layered/Containerfile index 12a089ee..142c487a 100644 --- a/images/layered/Containerfile +++ b/images/layered/Containerfile @@ -1,8 +1,8 @@ -ARG FRAPPE_BRANCH=version-15 +ARG FRAPPE_BRANCH=version-16 FROM frappe/build:${FRAPPE_BRANCH} AS builder -ARG FRAPPE_BRANCH=version-15 +ARG FRAPPE_BRANCH=version-16 ARG FRAPPE_PATH=https://github.com/frappe/frappe ARG APPS_JSON_BASE64 From 63b75a443103686e79a08e94b6674d7b23cf78f5 Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 3 Feb 2026 17:45:28 +0000 Subject: [PATCH 109/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 9ad64a1d..21ae91fe 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v15.95.2 +ERPNEXT_VERSION=v15.96.0 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index 0d06f6ad..60a48dcb 100644 --- a/pwd.yml +++ b/pwd.yml @@ -1,6 +1,6 @@ services: backend: - image: frappe/erpnext:v15.95.2 + image: frappe/erpnext:v15.96.0 networks: - frappe_network deploy: @@ -16,7 +16,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v15.95.2 + image: frappe/erpnext:v15.96.0 networks: - frappe_network deploy: @@ -45,7 +45,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v15.95.2 + image: frappe/erpnext:v15.96.0 networks: - frappe_network deploy: @@ -100,7 +100,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v15.95.2 + image: frappe/erpnext:v15.96.0 networks: - frappe_network depends_on: @@ -126,7 +126,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v15.95.2 + image: frappe/erpnext:v15.96.0 networks: - frappe_network deploy: @@ -145,7 +145,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v15.95.2 + image: frappe/erpnext:v15.96.0 networks: - frappe_network deploy: @@ -182,7 +182,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v15.95.2 + image: frappe/erpnext:v15.96.0 networks: - frappe_network deploy: @@ -196,7 +196,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v15.95.2 + image: frappe/erpnext:v15.96.0 networks: - frappe_network deploy: From 3d46cb84e08bf37273beb877a254b97131e6abf5 Mon Sep 17 00:00:00 2001 From: github-actions Date: Thu, 5 Feb 2026 11:24:40 +0000 Subject: [PATCH 110/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 21ae91fe..e70e5864 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v15.96.0 +ERPNEXT_VERSION=v15.96.1 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index 60a48dcb..acf7d5dc 100644 --- a/pwd.yml +++ b/pwd.yml @@ -1,6 +1,6 @@ services: backend: - image: frappe/erpnext:v15.96.0 + image: frappe/erpnext:v15.96.1 networks: - frappe_network deploy: @@ -16,7 +16,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v15.96.0 + image: frappe/erpnext:v15.96.1 networks: - frappe_network deploy: @@ -45,7 +45,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v15.96.0 + image: frappe/erpnext:v15.96.1 networks: - frappe_network deploy: @@ -100,7 +100,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v15.96.0 + image: frappe/erpnext:v15.96.1 networks: - frappe_network depends_on: @@ -126,7 +126,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v15.96.0 + image: frappe/erpnext:v15.96.1 networks: - frappe_network deploy: @@ -145,7 +145,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v15.96.0 + image: frappe/erpnext:v15.96.1 networks: - frappe_network deploy: @@ -182,7 +182,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v15.96.0 + image: frappe/erpnext:v15.96.1 networks: - frappe_network deploy: @@ -196,7 +196,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v15.96.0 + image: frappe/erpnext:v15.96.1 networks: - frappe_network deploy: From 99d9a1dc385d8a0660a67b0cbbfeac3d5229e58c Mon Sep 17 00:00:00 2001 From: RocketQuack <202538874+Rocket-Quack@users.noreply.github.com> Date: Fri, 6 Feb 2026 05:26:28 +0100 Subject: [PATCH 111/279] feat: add nginx-proxy with acme companion as an alternative to traefik (#1800) * refactor: move core nginx files into more recognizable folder structure * chore: include HTTPS_PUBLISH_PORT in example .env * feat: add nginx-proxy and acme-companion compose overrides * docs: add NGINX_PROXY_HOSTS to example.env * docs: add nginx-proxy overrides * docs: split docs, variables for usage of traefik or nginx-proxy * docs: update override notes for traefik proxy on separate stack * docs: split TLS/SSL overview and add own caddy guide * docs: add nginx-proxy + acme companion guide * docs: add nginx-proxy and acme single-server setup guide --- docs/02-setup/04-env-variables.md | 37 +++- docs/02-setup/05-overrides.md | 40 ++-- .../08-single-server-nginxproxy-example.md | 177 ++++++++++++++++++ docs/03-production/01-tls-ssl-setup.md | 60 ++++-- .../04-nginx-proxy-acme-companion.md | 82 ++++++++ docs/03-production/05-caddy-https.md | 44 +++++ .../02-windows-nginx-entrypoint-error.md | 2 +- docs/getting-started.md | 15 +- example.env | 9 + images/custom/Containerfile | 4 +- images/production/Containerfile | 4 +- overrides/compose.nginxproxy-ssl.yaml | 26 +++ overrides/compose.nginxproxy.yaml | 21 +++ .../{ => core/nginx}/nginx-entrypoint.sh | 0 .../{ => core/nginx}/nginx-template.conf | 0 15 files changed, 470 insertions(+), 51 deletions(-) create mode 100644 docs/02-setup/08-single-server-nginxproxy-example.md create mode 100644 docs/03-production/04-nginx-proxy-acme-companion.md create mode 100644 docs/03-production/05-caddy-https.md create mode 100644 overrides/compose.nginxproxy-ssl.yaml create mode 100644 overrides/compose.nginxproxy.yaml rename resources/{ => core/nginx}/nginx-entrypoint.sh (100%) rename resources/{ => core/nginx}/nginx-template.conf (100%) diff --git a/docs/02-setup/04-env-variables.md b/docs/02-setup/04-env-variables.md index a9c73a8a..54ed2956 100644 --- a/docs/02-setup/04-env-variables.md +++ b/docs/02-setup/04-env-variables.md @@ -43,12 +43,14 @@ Then edit `.env` and set variables according to your needs. --- -## HTTPS & SSL Configuration +## Reverse Proxy and SSL (HTTPS) Configuration -| Variable | Purpose | Default | When to Set | -| ------------------- | ------------------------------------------------------------- | ------- | ---------------------------------------- | -| `LETSENCRYPT_EMAIL` | Email for Let's Encrypt certificate registration | β€” | Required if using HTTPS override | -| `SITES_RULE` | List of domains for SSL (Traefik rule for TLS domain routing) | β€” | Required if using reverse proxy override | +### Traefik (compose.proxy.yaml / compose.https.yaml) + +| Variable | Purpose | Default | When to Set | +| ------------------- | ------------------------------------------------ | ------- | -------------------------------------------- | +| `LETSENCRYPT_EMAIL` | Email for Let's Encrypt certificate registration | - | Required for `compose.https.yaml` | +| `SITES_RULE` | Domains for routing (Traefik rule expression) | - | Required for Traefik routing/HTTPS overrides | **Format for `SITES_RULE`:** @@ -63,6 +65,28 @@ SITES_RULE=Host(`a.example.com`) || Host(`b.example.com`) > Note: The Traefik v3 migration is complete. Use `SITES_RULE` as a full v3 rule expression; `SITES` is deprecated. > Rule syntax now defaults to v3, so no `core.defaultRuleSyntax` or per-router `ruleSyntax` settings are required. +### nginx-proxy + acme-companion (compose.nginxproxy\*.yaml) + +| Variable | Purpose | Default | When to Set | +| ------------------- | ----------------------------------------- | ------- | ------------------------------------------ | +| `LETSENCRYPT_EMAIL` | Email for Let's Encrypt certificate | - | Required for `compose.nginxproxy-ssl.yaml` | +| `NGINX_PROXY_HOSTS` | Comma-separated hostnames for nginx-proxy | - | Required for `compose.nginxproxy*.yaml` | + +**Example:** + +```bash +NGINX_PROXY_HOSTS=example.com,www.example.com +``` + +> Note: Automatic certificates require port 80 to be reachable (HTTP-01). + +### Published Ports (Traefik and nginx-proxy) + +| Variable | Purpose | Default | When to Set | +| -------------------- | -------------------- | ------------------------------- | ---------------------------- | +| `HTTP_PUBLISH_PORT` | Published HTTP port | `80` (proxy) / `8080` (noproxy) | Change if port is in use | +| `HTTPS_PUBLISH_PORT` | Published HTTPS port | `443` | Change if port 443 is in use | + --- ## Site Configuration @@ -94,13 +118,12 @@ If your site is named `example.com` and you access it via that domain, no need t --- -## Nginx Proxy Configuration +## Frontend Nginx Configuration (inside the frontend container) | Variable | Purpose | Default | Allowed Values | | ---------------------- | ---------------------------------- | -------------- | -------------------------------------------- | | `BACKEND` | Backend service address and port | `0.0.0.0:8000` | `{host}:{port}` | | `SOCKETIO` | Socket.IO service address and port | `0.0.0.0:9000` | `{host}:{port}` | -| `HTTP_PUBLISH_PORT` | Published HTTP port | `8080` | Any available port | | `PROXY_READ_TIMEOUT` | Upstream request timeout | `120s` | Any nginx timeout value (e.g., `300s`, `5m`) | | `CLIENT_MAX_BODY_SIZE` | Maximum upload file size | `50m` | Any nginx size value (e.g., `100m`, `1g`) | diff --git a/docs/02-setup/05-overrides.md b/docs/02-setup/05-overrides.md index f1e274b1..0d7b6004 100644 --- a/docs/02-setup/05-overrides.md +++ b/docs/02-setup/05-overrides.md @@ -4,24 +4,26 @@ Overrides extend the base compose.yaml with additional services or modify existi docker compose -f compose.yaml -f overrides/compose.mariadb.yaml -f overrides/compose.redis.yaml config > compose.custom.yaml ``` -| Overrider | Purpose | Additional Info | -| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | -| **Database** | | | -| compose.mariadb.yaml | Adds MariaDB database service | set `DB_PASSWORD` or default Password will be used | -| compose.mariadb-secrets.yaml | Adds MariaDB with password from a secret file instead of environment variable | Set `DB_PASSWORD_SECRETS_FILE` to the path of your secret file | -| compose.mariadb-shared.yaml | Makes MariaDB available on a shared network (mariadb-network) for other services | set `DB_PASSWORD` | -| compose.postgres.yaml | Uses PostgreSQL instead of MariaDB as the database | set `DB_PASSWORD` | -| **Proxy** | | | -| compose.noproxy.yaml | Exposes the application directly on port `:8080` without a reverse proxy | | -| compose.proxy.yaml | Uses Traefik as HTTP reverse proxy on port `:80` | You can change the published port by setting `HTTP_PUBLISH_PORT` | -| compose.https.yaml | Uses Traefik as HTTPS reverse proxy on Port `:443` with automatic HTTP-to-HTTPS redirect | `SITES_RULE` and `LETSENCRYPT_EMAIL` must be set. `HTTP_PUBLISH_PORT` and `HTTPS_PUBLISH_PORT` can be set. | -| **Redis** | | | +| Overrider | Purpose | Additional Info | +| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | +| **Database** | | | +| compose.mariadb.yaml | Adds MariaDB database service | set `DB_PASSWORD` or default Password will be used | +| compose.mariadb-secrets.yaml | Adds MariaDB with password from a secret file instead of environment variable | Set `DB_PASSWORD_SECRETS_FILE` to the path of your secret file | +| compose.mariadb-shared.yaml | Makes MariaDB available on a shared network (mariadb-network) for other services | set `DB_PASSWORD` | +| compose.postgres.yaml | Uses PostgreSQL instead of MariaDB as the database | set `DB_PASSWORD` | +| **Proxy** | | | +| compose.noproxy.yaml | Exposes the application directly on port `:8080` without a reverse proxy | | +| compose.proxy.yaml | Uses Traefik as HTTP reverse proxy on port `:80` | You can change the published port by setting `HTTP_PUBLISH_PORT` | +| compose.https.yaml | Uses Traefik as HTTPS reverse proxy on Port `:443` with automatic HTTP-to-HTTPS redirect | `SITES_RULE` and `LETSENCRYPT_EMAIL` must be set. `HTTP_PUBLISH_PORT` and `HTTPS_PUBLISH_PORT` can be set. | +| compose.traefik.yaml | Runs a standalone Traefik proxy with dashboard (HTTP) on a shared `traefik-public` network | Use for multi-stack setups. Requires `TRAEFIK_DOMAIN` and `HASHED_PASSWORD`. | +| compose.traefik-ssl.yaml | Adds HTTPS and Let's Encrypt for the Traefik dashboard | Use with `compose.traefik.yaml`. Requires `EMAIL` and `TRAEFIK_DOMAIN`. Publishes `HTTPS_PUBLISH_PORT`. | +| compose.nginxproxy.yaml | Uses nginx-proxy as HTTP reverse proxy on port `:80` | Set `NGINX_PROXY_HOSTS`. Use with `compose.nginxproxy-ssl.yaml` for HTTPS. You can change the published port by setting `HTTP_PUBLISH_PORT` | +| compose.nginxproxy-ssl.yaml | Adds acme-companion for HTTPS on port `:443` with automatic certificates | Requires `compose.nginxproxy.yaml`. Set `NGINX_PROXY_HOSTS` and `LETSENCRYPT_EMAIL`. `HTTP_PUBLISH_PORT` and `HTTPS_PUBLISH_PORT` can be set. | +| **Redis** | | | | compose.redis.yaml | Adds Redis service for caching and background job queuing | | **TBD** | **The following overrides are available but lack documentation. If you use them and understand their purpose, please consider contributing to this documentation.** | -| compose.backup-cron.yaml | | | -| compose.custom-domain-ssl.yaml | | | -| compose.custom-domain.yaml | | | -| compose.multi-bench-ssl.yaml | | | -| compose.multi-bench.yaml | | | -| compose.traefik-ssl.yaml | | | -| compose.traefik.yaml | | | +| compose.backup-cron.yaml | | | +| compose.custom-domain-ssl.yaml | | | +| compose.custom-domain.yaml | | | +| compose.multi-bench-ssl.yaml | | | +| compose.multi-bench.yaml | | | diff --git a/docs/02-setup/08-single-server-nginxproxy-example.md b/docs/02-setup/08-single-server-nginxproxy-example.md new file mode 100644 index 00000000..ec9ef913 --- /dev/null +++ b/docs/02-setup/08-single-server-nginxproxy-example.md @@ -0,0 +1,177 @@ +# Single Server Example (nginx-proxy + acme-companion) + +This guide demonstrates a single-server setup using nginx-proxy and acme-companion for HTTPS. It is best for a small number of hostnames and a single bench. If you need multiple benches or advanced routing, use the Traefik-based example instead. + +We will setup the following: + +- Install Docker and Docker Compose v2 on a Linux server. +- Use nginx-proxy + acme-companion for HTTPS (Let's Encrypt). +- Install MariaDB and Redis via containers. +- Setup one project called `erpnext` with sites `erp.your-domain.com` and `crm.your-domain.com`. + +## Requirements + +- A server that can run Docker (recommended: 2 vCPU, 4 GB RAM, 50 GB SSD). +- A public domain with DNS control. +- Two subdomains pointing to your server IP (A/AAAA records): + - `erp.your-domain.com` + - `crm.your-domain.com` +- Ports 80 and 443 reachable from the internet (required for Let's Encrypt HTTP-01). + +### Install Docker + +Docker can be installed on a variety of systems. The easiest way to do this is with the convenience script. + +| Platform | Convenience script | Using repository | +| -------- | ------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | +| CentOS | [Link](https://docs.docker.com/engine/install/centos/#install-using-the-convenience-script) | [Link](https://docs.docker.com/engine/install/centos/#install-using-the-repository) | +| Debian | [Link](https://docs.docker.com/engine/install/debian/#install-using-the-convenience-script) | [Link](https://docs.docker.com/engine/install/debian/#install-using-the-repository) | +| Ubuntu | [Link](https://docs.docker.com/engine/install/ubuntu/#install-using-the-convenience-script) | [Link](https://docs.docker.com/engine/install/ubuntu/#install-using-the-repository) | +| Fedora | [Link](https://docs.docker.com/engine/install/fedora/#install-using-the-convenience-script) | [Link](https://docs.docker.com/engine/install/fedora/#install-using-the-repository) | + +Then do the post-installation steps. This will ensure that the permissions are easier to use and that Docker will start up with the System. [Post-Installation Steps](https://docs.docker.com/engine/install/linux-postinstall/) + +### Prepare + +Clone `frappe_docker` and change the current working directory to the repo. + +```shell +git clone https://github.com/frappe/frappe_docker +cd frappe_docker +``` + +Create a configuration directory: + +```shell +mkdir ~/gitops +``` + +## Optional: Build a custom image + +If you need extra apps (beyond Frappe/ERPNext), build a custom image. Otherwise, skip this section and use the default images. + +Create `apps.json` (each entry is a Git repo + branch): + +```shell +cat > ~/gitops/apps.json <<'EOF' +[ + { + "url": "https://github.com/frappe/erpnext", + "branch": "version-16" + }, + { + "url": "https://github.com/frappe/payments", + "branch": "version-16" + } +] +EOF +``` + +Example for CRM only: + +```shell +cat > ~/gitops/apps.json <<'EOF' +[ + { + "url": "https://github.com/frappe/crm", + "branch": "main" + } +] +EOF +``` + +Generate the BASE64 value and build: + +```shell +export APPS_JSON_BASE64=$(base64 -w 0 ~/gitops/apps.json) + +docker build \ + --build-arg=FRAPPE_PATH=https://github.com/frappe/frappe \ + --build-arg=FRAPPE_BRANCH=version-16 \ + --build-arg=APPS_JSON_BASE64=$APPS_JSON_BASE64 \ + --tag=my-erpnext-prod-image:16.0.0 \ + --file=images/layered/Containerfile . +``` + +If `base64 -w 0` is not available on your system, use: + +```shell +export APPS_JSON_BASE64=$(base64 ~/gitops/apps.json | tr -d '\n') +``` + +### Configure environment + +Create an environment file for the bench: + +```shell +cp example.env ~/gitops/erpnext.env +sed -i 's/DB_PASSWORD=123/DB_PASSWORD=changeit/g' ~/gitops/erpnext.env +echo 'NGINX_PROXY_HOSTS=erp.your-domain.com,crm.your-domain.com' >> ~/gitops/erpnext.env +echo 'LETSENCRYPT_EMAIL=admin@your-domain.com' >> ~/gitops/erpnext.env +``` + +Notes: + +- Replace `changeit` with a strong password. +- Replace domains and email with your production values. +- `NGINX_PROXY_HOSTS` is a comma-separated list without spaces. +- If you built a custom image, add: + +```shell +echo "CUSTOM_IMAGE=my-erpnext-prod-image" >> ~/gitops/erpnext.env +echo "CUSTOM_TAG=16.0.0" >> ~/gitops/erpnext.env +``` + +### Generate compose config + +Create the rendered compose file: + +```shell +docker compose --project-name erpnext \ + --env-file ~/gitops/erpnext.env \ + -f compose.yaml \ + -f overrides/compose.mariadb.yaml \ + -f overrides/compose.redis.yaml \ + -f overrides/compose.nginxproxy.yaml \ + -f overrides/compose.nginxproxy-ssl.yaml config > ~/gitops/erpnext.yaml +``` + +Start the stack: + +```shell +docker compose --project-name erpnext -f ~/gitops/erpnext.yaml up -d +``` + +This starts MariaDB and Redis containers as part of the same stack. + +### Create sites + +```shell +# erp.your-domain.com +docker compose --project-name erpnext exec backend \ + bench new-site --mariadb-user-host-login-scope=% --db-root-password changeit --install-app erpnext --admin-password changeit erp.your-domain.com + +# crm.your-domain.com +docker compose --project-name erpnext exec backend \ + bench new-site --mariadb-user-host-login-scope=% --db-root-password changeit --install-app erpnext --admin-password changeit crm.your-domain.com +``` + +### Notes + +- Let's Encrypt requires ports 80 and 443 to be reachable from the internet. +- If you cannot expose these ports (LAN-only), omit `compose.nginxproxy-ssl.yaml` and use HTTP or a local TLS proxy like Caddy. +- Replace `changeit` with a strong DB root password and set a strong admin password per site. + +### Site operations + +Refer: [site operations](../04-operations/01-site-operations.md) + +### Troubleshooting (ACME / certificates) + +- **No certificate issued:** Verify DNS points to the server IP and ports 80/443 are reachable from the internet. +- **ACME errors in logs:** Check `acme-companion` logs for the exact challenge error. +- **Wrong hostname:** Ensure the domain is included in `NGINX_PROXY_HOSTS` and that you restarted the stack after edits. + +--- + +**Back:** [Single Server Example (Traefik)](07-single-server-example.md) diff --git a/docs/03-production/01-tls-ssl-setup.md b/docs/03-production/01-tls-ssl-setup.md index 07a0787b..b88fc8c1 100644 --- a/docs/03-production/01-tls-ssl-setup.md +++ b/docs/03-production/01-tls-ssl-setup.md @@ -1,25 +1,53 @@ -# Accessing ERPNext through https on local deployment +# TLS/SSL Setup Overview -- ERPNext container deployment can be accessed through https easily using Caddy web server, Caddy will be used as reverse proxy and forward traffics to the frontend container. +Frappe Docker supports multiple TLS/SSL approaches. Choose the one that matches your routing needs and where you want the proxy to run. -### Prerequisites +## Options -- Caddy -- Adding a domain name to hosts file +### Traefik (built-in HTTPS) -#### Installation of caddy webserver +- Use `overrides/compose.https.yaml` +- Best for multi-site setups and advanced routing rules +- Requires `SITES_RULE` and `LETSENCRYPT_EMAIL` +- See [Environment Variables](../02-setup/04-env-variables.md) and [Setup Examples](../02-setup/06-setup-examples.md#example-3-production-setup-with-https) -- Follow the official Caddy website for the installation guide https://caddyserver.com/docs/install - After completing the installation open the configuration file of Caddy ( You find the config file in ` /etc/caddy/Caddyfile`), add the following configuration to forward traffics to the ERPNext frontend container +#### Traefik deployment models -```js -erp.localdev.net { - tls internal +- **Single stack (Traefik inside the stack):** + - Use `compose.proxy.yaml` (HTTP) or `compose.https.yaml` (HTTPS) + - Traefik runs as `proxy` in the same stack +- **Central Traefik for multiple stacks:** + - Run a dedicated Traefik stack with `compose.traefik.yaml` (and optional `compose.traefik-ssl.yaml` for the dashboard) + - Each Frappe stack uses `compose.multi-bench.yaml` (and optional `compose.multi-bench-ssl.yaml`) + - This connects stacks to the shared `traefik-public` network - reverse_proxy localhost:8085 { +### nginx-proxy + acme-companion - } -} -``` +- Use `overrides/compose.nginxproxy.yaml` plus `overrides/compose.nginxproxy-ssl.yaml` +- Simple host-based routing for single-bench or small setups +- Requires `NGINX_PROXY_HOSTS` and `LETSENCRYPT_EMAIL` +- See [nginx-proxy + acme-companion](04-nginx-proxy-acme-companion.md) -- Caddy's root certificate must be added to other computers if computers from different networks access the ERPNext through https. +## Traefik vs nginx-proxy + acme-companion + +| Topic | Traefik (compose.https.yaml) | nginx-proxy + acme-companion | +| ------------------- | --------------------------------------------- | ------------------------------------------------------------------------------ | +| Configuration | Labels with `SITES_RULE` expression | Environment variables (`NGINX_PROXY_HOSTS`) | +| Routing | Flexible (rules, headers, paths) | Host-based only | +| Multi-site | Strong | Works for simple host lists | +| TLS/ACME | Built-in | Separate companion container | +| Certificate storage | `cert-data` volume (`/letsencrypt/acme.json`) | `nginx-proxy-certs` + `acme-data` volumes (`/etc/nginx/certs`, `/etc/acme.sh`) | +| Complexity | Moderate | Low | +| Observability | Optional dashboard (not enabled here) | No built-in dashboard | + +### Caddy (external reverse proxy) + +- Run Caddy on the host and proxy to the frontend container +- Useful for local HTTPS or when you already use Caddy +- See [Caddy reverse proxy](05-caddy-https.md) + +## Common requirements + +- DNS must point to the server for public TLS certificates +- Ports 80 and 443 must be reachable for HTTP-01 challenges +- Use `HTTP_PUBLISH_PORT` and `HTTPS_PUBLISH_PORT` if you need non-default ports diff --git a/docs/03-production/04-nginx-proxy-acme-companion.md b/docs/03-production/04-nginx-proxy-acme-companion.md new file mode 100644 index 00000000..15c474eb --- /dev/null +++ b/docs/03-production/04-nginx-proxy-acme-companion.md @@ -0,0 +1,82 @@ +# nginx-proxy + acme-companion (HTTPS) + +This guide explains how to use nginx-proxy with acme-companion to provide HTTPS for a Frappe Docker stack. + +## When to choose this + +- You want a simple, host-based reverse proxy +- You run a single bench or only a few hostnames +- You prefer environment-variable based configuration + +If you need advanced routing or complex multi-site setups, **Traefik** is usually the better choice. + +## Prerequisites + +- Public DNS points your domain(s) to the server +- Ports 80 and 443 are reachable (HTTP-01 challenge) +- Docker and Docker Compose v2 installed + +## Required environment variables + +Set these in `.env`: + +```bash +NGINX_PROXY_HOSTS=erp.your-domain.com +LETSENCRYPT_EMAIL=admin@your-domain.com +``` + +Multiple hostnames (comma-separated, no spaces): + +```bash +NGINX_PROXY_HOSTS=erp.your-domain.com,erp2.your-domain.com +LETSENCRYPT_EMAIL=admin@example.com +``` + +Optional (non-default ports): + +```bash +HTTP_PUBLISH_PORT=80 +HTTPS_PUBLISH_PORT=443 +``` + +## Compose setup (HTTPS) + +For HTTPS you must include both overrides: + +- `overrides/compose.nginxproxy.yaml` (nginx-proxy, VIRTUAL_HOST) +- `overrides/compose.nginxproxy-ssl.yaml` (acme-companion, LETSENCRYPT_HOST) + +Example: + +```sh +docker compose -f compose.yaml \ + -f overrides/compose.mariadb.yaml \ + -f overrides/compose.redis.yaml \ + -f overrides/compose.nginxproxy.yaml \ + -f overrides/compose.nginxproxy-ssl.yaml \ + config > ~/gitops/docker-compose.yml + +docker compose --project-name -f ~/gitops/docker-compose.yml up -d +``` + +> If you use external MariaDB/Redis, replace the database and Redis overrides accordingly. + +## How hostnames are applied + +`NGINX_PROXY_HOSTS` is a comma-separated list of hostnames. The overrides apply it as: + +- `VIRTUAL_HOST` for nginx-proxy routing +- `LETSENCRYPT_HOST` for certificate issuance + +## Verify + +Check logs for certificate issuance and proxy status: + +```sh +docker compose --project-name -f ~/gitops/docker-compose.yml logs -f nginx-proxy +docker compose --project-name -f ~/gitops/docker-compose.yml logs -f acme-companion +``` + +> Depending on the registrar, the assignment may take some time, whereby it must also be ensured that A and AAAA records are correctly directed to the server for the issuance of the certificate, if necessary. + +See also: [Environment Variables](../02-setup/04-env-variables.md) and [TLS/SSL Setup Overview](01-tls-ssl-setup.md). diff --git a/docs/03-production/05-caddy-https.md b/docs/03-production/05-caddy-https.md new file mode 100644 index 00000000..a8683c5d --- /dev/null +++ b/docs/03-production/05-caddy-https.md @@ -0,0 +1,44 @@ +# Caddy reverse proxy (local HTTPS) + +This guide shows how to use Caddy as an external reverse proxy in front of the frontend container. It is most useful for local HTTPS or internal networks. + +## Prerequisites + +- Expose the frontend container on a host port (default 8080) +- Add a local domain to your hosts file (or use internal DNS) +- Install Caddy + +## Step 1: Expose the frontend service + +Include the no-proxy override so the frontend is reachable on the host: + +```sh +docker compose -f compose.yaml \ + -f overrides/compose.mariadb.yaml \ + -f overrides/compose.redis.yaml \ + -f overrides/compose.noproxy.yaml \ + config > ~/gitops/docker-compose.yml + +docker compose --project-name -f ~/gitops/docker-compose.yml up -d +``` + +If you changed the HTTP port, note the value of `HTTP_PUBLISH_PORT` for the next step. + +## Step 2: Configure Caddy + +Add a site block to your Caddyfile (usually `/etc/caddy/Caddyfile`): + +```caddy +erp.localdev.net { + tls internal + reverse_proxy localhost:8080 +} +``` + +Replace `8080` with your published frontend port if you changed it. + +## Step 3: Trust the Caddy root certificate + +When using `tls internal`, Caddy issues certificates from its internal CA. Import and trust the Caddy root certificate on any client that needs to access the site. + +See also: [TLS/SSL Setup Overview](01-tls-ssl-setup.md). diff --git a/docs/07-troubleshooting/02-windows-nginx-entrypoint-error.md b/docs/07-troubleshooting/02-windows-nginx-entrypoint-error.md index 7be1c2ca..112ed0ea 100644 --- a/docs/07-troubleshooting/02-windows-nginx-entrypoint-error.md +++ b/docs/07-troubleshooting/02-windows-nginx-entrypoint-error.md @@ -8,5 +8,5 @@ On Windows, files often have `CRLF` line endings, while Linux systems expect `LF - **Convert Line Endings using `dos2unix`:** ```bash - dos2unix resources/nginx-entrypoint.sh + dos2unix resources/core/nginx/nginx-entrypoint.sh ``` diff --git a/docs/getting-started.md b/docs/getting-started.md index f87b8617..e67f7415 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -93,8 +93,15 @@ Docker Compose "overrides" that extend the base compose.yaml for different scena - **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 -- **compose.https.yaml** - Adds SSL/TLS certificate management +- **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 @@ -103,8 +110,8 @@ Docker Compose "overrides" that extend the base compose.yaml for different scena ### πŸ“ resources/ - Runtime Templates -- **nginx-entrypoint.sh** - Dynamic Nginx configuration generator script -- **nginx-template.conf** - Nginx configuration template with variable substitution +- **core/nginx/nginx-entrypoint.sh** - Dynamic Nginx configuration generator script +- **core/nginx/nginx-template.conf** - Nginx configuration template with variable substitution ## Custom Apps Explained diff --git a/example.env b/example.env index e70e5864..56550219 100644 --- a/example.env +++ b/example.env @@ -29,6 +29,9 @@ FRAPPE_SITE_NAME_HEADER= # Default value is `8080`. HTTP_PUBLISH_PORT= +# Default value is `443`. +HTTPS_PUBLISH_PORT= + # Default value is `127.0.0.1`. Set IP address as our trusted upstream address. UPSTREAM_REAL_IP_ADDRESS= @@ -49,8 +52,14 @@ PROXY_READ_TIMEOUT= # Necessary if the upload limit in the frappe application is increased CLIENT_MAX_BODY_SIZE= +# Only with traefik overrides # Single site: SITES_RULE=Host(`erp.example.com`) # Multiple sites: SITES_RULE=Host(`a.example.com`) || Host(`b.example.com`) # More https://doc.traefik.io/traefik/routing/routers/#rule # About acme https://doc.traefik.io/traefik/https/acme/#domain-definition SITES_RULE=Host(`erp.example.com`) + +# Only with nginxproxy overrides +# Single site: NGINX_PROXY_HOSTS=erp.example.com +# Multiple sites: NGINX_PROXY_HOSTS=erp.example.com,www.erp.example.com +NGINX_PROXY_HOSTS=erp.example.com diff --git a/images/custom/Containerfile b/images/custom/Containerfile index 06182d42..21523892 100644 --- a/images/custom/Containerfile +++ b/images/custom/Containerfile @@ -2,8 +2,8 @@ ARG PYTHON_VERSION=3.11.6 ARG DEBIAN_BASE=bookworm FROM python:${PYTHON_VERSION}-slim-${DEBIAN_BASE} AS base -COPY resources/nginx-template.conf /templates/nginx/frappe.conf.template -COPY resources/nginx-entrypoint.sh /usr/local/bin/nginx-entrypoint.sh +COPY resources/core/nginx/nginx-template.conf /templates/nginx/frappe.conf.template +COPY resources/core/nginx/nginx-entrypoint.sh /usr/local/bin/nginx-entrypoint.sh ARG WKHTMLTOPDF_VERSION=0.12.6.1-3 ARG WKHTMLTOPDF_DISTRO=bookworm diff --git a/images/production/Containerfile b/images/production/Containerfile index 563bc763..d44f3878 100644 --- a/images/production/Containerfile +++ b/images/production/Containerfile @@ -69,8 +69,8 @@ RUN useradd -ms /bin/bash frappe \ && chown -R frappe:frappe /var/lib/nginx \ && chown -R frappe:frappe /run/nginx.pid -COPY resources/nginx-template.conf /templates/nginx/frappe.conf.template -COPY resources/nginx-entrypoint.sh /usr/local/bin/nginx-entrypoint.sh +COPY resources/core/nginx/nginx-template.conf /templates/nginx/frappe.conf.template +COPY resources/core/nginx/nginx-entrypoint.sh /usr/local/bin/nginx-entrypoint.sh FROM base AS build diff --git a/overrides/compose.nginxproxy-ssl.yaml b/overrides/compose.nginxproxy-ssl.yaml new file mode 100644 index 00000000..d8e66ead --- /dev/null +++ b/overrides/compose.nginxproxy-ssl.yaml @@ -0,0 +1,26 @@ +services: + frontend: + environment: + LETSENCRYPT_HOST: ${NGINX_PROXY_HOSTS:?No NGINX_PROXY_HOSTS set} + + nginx-proxy: + ports: + - ${HTTP_PUBLISH_PORT:-80}:80 + - ${HTTPS_PUBLISH_PORT:-443}:443 + + acme-companion: + image: nginxproxy/acme-companion:latest + restart: unless-stopped + environment: + DEFAULT_EMAIL: ${LETSENCRYPT_EMAIL:?No LETSENCRYPT_EMAIL set} + volumes: + - nginx-proxy-certs:/etc/nginx/certs + - nginx-proxy-html:/usr/share/nginx/html + - nginx-proxy-vhost:/etc/nginx/vhost.d + - acme-data:/etc/acme.sh + - /var/run/docker.sock:/var/run/docker.sock:ro + depends_on: + - nginx-proxy + +volumes: + acme-data: diff --git a/overrides/compose.nginxproxy.yaml b/overrides/compose.nginxproxy.yaml new file mode 100644 index 00000000..f1f4ebf5 --- /dev/null +++ b/overrides/compose.nginxproxy.yaml @@ -0,0 +1,21 @@ +services: + frontend: + environment: + VIRTUAL_HOST: ${NGINX_PROXY_HOSTS:?No NGINX_PROXY_HOSTS set} + VIRTUAL_PORT: 8080 + + nginx-proxy: + image: nginxproxy/nginx-proxy:alpine + restart: unless-stopped + ports: + - ${HTTP_PUBLISH_PORT:-80}:80 + volumes: + - nginx-proxy-certs:/etc/nginx/certs + - nginx-proxy-html:/usr/share/nginx/html + - nginx-proxy-vhost:/etc/nginx/vhost.d + - /var/run/docker.sock:/tmp/docker.sock:ro + +volumes: + nginx-proxy-certs: + nginx-proxy-html: + nginx-proxy-vhost: diff --git a/resources/nginx-entrypoint.sh b/resources/core/nginx/nginx-entrypoint.sh similarity index 100% rename from resources/nginx-entrypoint.sh rename to resources/core/nginx/nginx-entrypoint.sh diff --git a/resources/nginx-template.conf b/resources/core/nginx/nginx-template.conf similarity index 100% rename from resources/nginx-template.conf rename to resources/core/nginx/nginx-template.conf From abd0554e6581b3880a2162b3d839699ac69ae84f Mon Sep 17 00:00:00 2001 From: david-loe <56305409+david-loe@users.noreply.github.com> Date: Sat, 7 Feb 2026 09:56:19 +0100 Subject: [PATCH 112/279] changed _V14 to _PREV --- images/bench/Dockerfile | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/images/bench/Dockerfile b/images/bench/Dockerfile index 59b3360c..7591eec4 100644 --- a/images/bench/Dockerfile +++ b/images/bench/Dockerfile @@ -99,18 +99,18 @@ USER frappe WORKDIR /home/frappe # Install Python via pyenv -ENV PYTHON_VERSION_V14=3.10.13 +ENV PYTHON_VERSION_PREV=3.12.12 ENV PYTHON_VERSION=3.14.2 ENV PYENV_ROOT=/home/frappe/.pyenv ENV PATH=$PYENV_ROOT/shims:$PYENV_ROOT/bin:$PATH # From https://github.com/pyenv/pyenv#basic-github-checkout RUN git clone --depth 1 https://github.com/pyenv/pyenv.git .pyenv \ - && pyenv install $PYTHON_VERSION_V14 \ + && pyenv install $PYTHON_VERSION_PREV \ && pyenv install $PYTHON_VERSION \ - && PYENV_VERSION=$PYTHON_VERSION_V14 pip install --no-cache-dir virtualenv \ + && PYENV_VERSION=$PYTHON_VERSION_PREV pip install --no-cache-dir virtualenv \ && PYENV_VERSION=$PYTHON_VERSION pip install --no-cache-dir virtualenv \ - && pyenv global $PYTHON_VERSION $PYTHON_VERSION_v14 \ + && pyenv global $PYTHON_VERSION $PYTHON_VERSION_PREV \ && sed -Ei -e '/^([^#]|$)/ {a export PYENV_ROOT="/home/frappe/.pyenv" a export PATH="$PYENV_ROOT/bin:$PATH" a ' -e ':a' -e '$!{n;ba};}' ~/.profile \ && echo 'eval "$(pyenv init --path)"' >>~/.profile \ && echo 'eval "$(pyenv init -)"' >>~/.bashrc @@ -126,15 +126,15 @@ RUN git clone ${GIT_REPO} --depth 1 -b ${GIT_BRANCH} .bench \ && echo "export BENCH_DEVELOPER=1" >>/home/frappe/.bashrc # Install Node via nvm -ENV NODE_VERSION_14=16.20.2 -ENV NODE_VERSION=24.12.0 +ENV NODE_VERSION_PREV=22.22.0 +ENV NODE_VERSION=24.13.0 ENV NVM_DIR=/home/frappe/.nvm ENV PATH=${NVM_DIR}/versions/node/v${NODE_VERSION}/bin/:${PATH} RUN wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.5/install.sh | bash \ && . ${NVM_DIR}/nvm.sh \ - && nvm install ${NODE_VERSION_14} \ - && nvm use v${NODE_VERSION_14} \ + && nvm install ${NODE_VERSION_PREV} \ + && nvm use v${NODE_VERSION_PREV} \ && npm install -g yarn \ && nvm install ${NODE_VERSION} \ && nvm use v${NODE_VERSION} \ From 4de2ce53078ebf6dcf6d1d60ed2c79ac0bab22da Mon Sep 17 00:00:00 2001 From: david-loe <56305409+david-loe@users.noreply.github.com> Date: Sat, 7 Feb 2026 09:57:45 +0100 Subject: [PATCH 113/279] Update FRAPPE_BRANCH to version-16 --- images/custom/Containerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/images/custom/Containerfile b/images/custom/Containerfile index ebe7eccb..c1467605 100644 --- a/images/custom/Containerfile +++ b/images/custom/Containerfile @@ -115,7 +115,7 @@ RUN if [ -n "${APPS_JSON_BASE64}" ]; then \ USER frappe -ARG FRAPPE_BRANCH=version-15 +ARG FRAPPE_BRANCH=version-16 ARG FRAPPE_PATH=https://github.com/frappe/frappe RUN export APP_INSTALL_ARGS="" && \ if [ -n "${APPS_JSON_BASE64}" ]; then \ From ef90ecb5aa629f2c222ae53b9faef27ace7d9eed Mon Sep 17 00:00:00 2001 From: Daniel Radl Date: Sat, 7 Feb 2026 17:41:21 +0100 Subject: [PATCH 114/279] Update workflow to remove v14 and use v16 --- .github/workflows/build_stable.yml | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/.github/workflows/build_stable.yml b/.github/workflows/build_stable.yml index ab6469de..6f0535d1 100644 --- a/.github/workflows/build_stable.yml +++ b/.github/workflows/build_stable.yml @@ -30,18 +30,6 @@ on: workflow_dispatch: jobs: - v14: - uses: ./.github/workflows/docker-build-push.yml - with: - repo: erpnext - version: "14" - push: ${{ github.repository == 'frappe/frappe_docker' && github.event_name != 'pull_request' }} - python_version: 3.10.13 - node_version: 16.20.2 - secrets: - DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }} - DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} - v15: uses: ./.github/workflows/docker-build-push.yml with: @@ -70,7 +58,7 @@ jobs: name: Update example.env and pwd.yml runs-on: ubuntu-latest if: ${{ github.repository == 'frappe/frappe_docker' && github.event_name != 'pull_request' }} - needs: v15 + needs: v16 steps: - name: Checkout @@ -79,10 +67,10 @@ jobs: - name: Setup Python uses: actions/setup-python@v6 with: - python-version: "3.10" + python-version: "3.14.2" - name: Get latest versions - run: python3 ./.github/scripts/get_latest_tags.py --repo erpnext --version 15 + run: python3 ./.github/scripts/get_latest_tags.py --repo erpnext --version 16 - name: Update run: | @@ -108,7 +96,7 @@ jobs: name: Release Helm runs-on: ubuntu-latest if: ${{ github.repository == 'frappe/frappe_docker' && github.event_name != 'pull_request' }} - needs: v15 + needs: v16 steps: - name: Setup deploy key From 1ad2bba116da1537cff257e95b40ff67d0774593 Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 11 Feb 2026 05:23:38 +0000 Subject: [PATCH 115/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 56550219..25f2c6a5 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v15.96.1 +ERPNEXT_VERSION=v16.4.1 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index acf7d5dc..ad50cca6 100644 --- a/pwd.yml +++ b/pwd.yml @@ -1,6 +1,6 @@ services: backend: - image: frappe/erpnext:v15.96.1 + image: frappe/erpnext:v16.4.1 networks: - frappe_network deploy: @@ -16,7 +16,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v15.96.1 + image: frappe/erpnext:v16.4.1 networks: - frappe_network deploy: @@ -45,7 +45,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v15.96.1 + image: frappe/erpnext:v16.4.1 networks: - frappe_network deploy: @@ -100,7 +100,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v15.96.1 + image: frappe/erpnext:v16.4.1 networks: - frappe_network depends_on: @@ -126,7 +126,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v15.96.1 + image: frappe/erpnext:v16.4.1 networks: - frappe_network deploy: @@ -145,7 +145,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v15.96.1 + image: frappe/erpnext:v16.4.1 networks: - frappe_network deploy: @@ -182,7 +182,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v15.96.1 + image: frappe/erpnext:v16.4.1 networks: - frappe_network deploy: @@ -196,7 +196,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v15.96.1 + image: frappe/erpnext:v16.4.1 networks: - frappe_network deploy: From d56cd8851eb51129881ada6017f91c1e36064c1c Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 11 Feb 2026 06:29:21 +0000 Subject: [PATCH 116/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 25f2c6a5..11e839e2 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v16.4.1 +ERPNEXT_VERSION=v16.5.0 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index ad50cca6..ecb82352 100644 --- a/pwd.yml +++ b/pwd.yml @@ -1,6 +1,6 @@ services: backend: - image: frappe/erpnext:v16.4.1 + image: frappe/erpnext:v16.5.0 networks: - frappe_network deploy: @@ -16,7 +16,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v16.4.1 + image: frappe/erpnext:v16.5.0 networks: - frappe_network deploy: @@ -45,7 +45,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v16.4.1 + image: frappe/erpnext:v16.5.0 networks: - frappe_network deploy: @@ -100,7 +100,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v16.4.1 + image: frappe/erpnext:v16.5.0 networks: - frappe_network depends_on: @@ -126,7 +126,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v16.4.1 + image: frappe/erpnext:v16.5.0 networks: - frappe_network deploy: @@ -145,7 +145,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v16.4.1 + image: frappe/erpnext:v16.5.0 networks: - frappe_network deploy: @@ -182,7 +182,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v16.4.1 + image: frappe/erpnext:v16.5.0 networks: - frappe_network deploy: @@ -196,7 +196,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v16.4.1 + image: frappe/erpnext:v16.5.0 networks: - frappe_network deploy: From f5598cd5e217534ab5d0eb0f2b7ea7df24f60f8d Mon Sep 17 00:00:00 2001 From: Thomas Date: Wed, 11 Feb 2026 17:00:48 +0100 Subject: [PATCH 117/279] fix: enable pnpm via corepack for apps that require it (e.g. drive) --- images/custom/Containerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/images/custom/Containerfile b/images/custom/Containerfile index 97b9906e..a4a9ca51 100644 --- a/images/custom/Containerfile +++ b/images/custom/Containerfile @@ -46,6 +46,7 @@ RUN useradd -ms /bin/bash frappe \ && nvm install ${NODE_VERSION} \ && nvm use v${NODE_VERSION} \ && npm install -g yarn \ + && corepack enable pnpm \ && nvm alias default v${NODE_VERSION} \ && rm -rf ${NVM_DIR}/.cache \ && echo 'export NVM_DIR="/home/frappe/.nvm"' >>/home/frappe/.bashrc \ From 8b3def7162b5b868c54c83b2e0901ff1fb784354 Mon Sep 17 00:00:00 2001 From: trustedcomputer Date: Mon, 16 Feb 2026 06:51:59 -0800 Subject: [PATCH 118/279] feat: add chromium pdf generator support --- compose.yaml | 1 + images/custom/Containerfile | 2 ++ images/production/Containerfile | 2 ++ 3 files changed, 5 insertions(+) diff --git a/compose.yaml b/compose.yaml index edf406ca..c1f2eb63 100644 --- a/compose.yaml +++ b/compose.yaml @@ -33,6 +33,7 @@ services: bench set-config -g redis_queue "redis://$$REDIS_QUEUE"; bench set-config -g redis_socketio "redis://$$REDIS_QUEUE"; bench set-config -gp socketio_port $$SOCKETIO_PORT; + bench set-config -g chromium_path /usr/bin/chromium-headless-shell; environment: DB_HOST: ${DB_HOST:-} DB_PORT: ${DB_PORT:-} diff --git a/images/custom/Containerfile b/images/custom/Containerfile index 97b9906e..eefa4e6c 100644 --- a/images/custom/Containerfile +++ b/images/custom/Containerfile @@ -25,6 +25,8 @@ RUN useradd -ms /bin/bash frappe \ libharfbuzz0b \ libpangoft2-1.0-0 \ libpangocairo-1.0-0 \ + #Chromium + chromium-headless-shell \ # For backups restic \ gpg \ diff --git a/images/production/Containerfile b/images/production/Containerfile index abebba86..4a8c7f4c 100644 --- a/images/production/Containerfile +++ b/images/production/Containerfile @@ -22,6 +22,8 @@ RUN useradd -ms /bin/bash frappe \ libharfbuzz0b \ libpangoft2-1.0-0 \ libpangocairo-1.0-0 \ + #Chromium + chromium-headless-shell \ # For backups restic \ gpg \ From 7325c316b89cdcdf6b358b8842e594dca076f1c2 Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 17 Feb 2026 14:39:17 +0000 Subject: [PATCH 119/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 11e839e2..8b45e6d7 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v16.5.0 +ERPNEXT_VERSION=v16.6.0 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index ecb82352..bfae377b 100644 --- a/pwd.yml +++ b/pwd.yml @@ -1,6 +1,6 @@ services: backend: - image: frappe/erpnext:v16.5.0 + image: frappe/erpnext:v16.6.0 networks: - frappe_network deploy: @@ -16,7 +16,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v16.5.0 + image: frappe/erpnext:v16.6.0 networks: - frappe_network deploy: @@ -45,7 +45,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v16.5.0 + image: frappe/erpnext:v16.6.0 networks: - frappe_network deploy: @@ -100,7 +100,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v16.5.0 + image: frappe/erpnext:v16.6.0 networks: - frappe_network depends_on: @@ -126,7 +126,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v16.5.0 + image: frappe/erpnext:v16.6.0 networks: - frappe_network deploy: @@ -145,7 +145,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v16.5.0 + image: frappe/erpnext:v16.6.0 networks: - frappe_network deploy: @@ -182,7 +182,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v16.5.0 + image: frappe/erpnext:v16.6.0 networks: - frappe_network deploy: @@ -196,7 +196,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v16.5.0 + image: frappe/erpnext:v16.6.0 networks: - frappe_network deploy: From 38d96e1d9529711b55cd8d803127f5b4a6375507 Mon Sep 17 00:00:00 2001 From: RocketQuack <202538874+Rocket-Quack@users.noreply.github.com> Date: Wed, 18 Feb 2026 17:31:35 +0100 Subject: [PATCH 120/279] fix: Add label for acme discovery to nginx-proxy --- overrides/compose.nginxproxy-ssl.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/overrides/compose.nginxproxy-ssl.yaml b/overrides/compose.nginxproxy-ssl.yaml index d8e66ead..4ef0d7ff 100644 --- a/overrides/compose.nginxproxy-ssl.yaml +++ b/overrides/compose.nginxproxy-ssl.yaml @@ -4,6 +4,8 @@ services: LETSENCRYPT_HOST: ${NGINX_PROXY_HOSTS:?No NGINX_PROXY_HOSTS set} nginx-proxy: + labels: + com.github.nginx-proxy.nginx: "true" ports: - ${HTTP_PUBLISH_PORT:-80}:80 - ${HTTPS_PUBLISH_PORT:-443}:443 From 878fd8551188df0eea1099b24a5d34615d90e7cd Mon Sep 17 00:00:00 2001 From: github-actions Date: Thu, 19 Feb 2026 05:29:17 +0000 Subject: [PATCH 121/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 8b45e6d7..e4dc5246 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v16.6.0 +ERPNEXT_VERSION=v16.6.1 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index bfae377b..ab41e301 100644 --- a/pwd.yml +++ b/pwd.yml @@ -1,6 +1,6 @@ services: backend: - image: frappe/erpnext:v16.6.0 + image: frappe/erpnext:v16.6.1 networks: - frappe_network deploy: @@ -16,7 +16,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v16.6.0 + image: frappe/erpnext:v16.6.1 networks: - frappe_network deploy: @@ -45,7 +45,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v16.6.0 + image: frappe/erpnext:v16.6.1 networks: - frappe_network deploy: @@ -100,7 +100,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v16.6.0 + image: frappe/erpnext:v16.6.1 networks: - frappe_network depends_on: @@ -126,7 +126,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v16.6.0 + image: frappe/erpnext:v16.6.1 networks: - frappe_network deploy: @@ -145,7 +145,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v16.6.0 + image: frappe/erpnext:v16.6.1 networks: - frappe_network deploy: @@ -182,7 +182,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v16.6.0 + image: frappe/erpnext:v16.6.1 networks: - frappe_network deploy: @@ -196,7 +196,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v16.6.0 + image: frappe/erpnext:v16.6.1 networks: - frappe_network deploy: From 2c43d346460cedb36f608880b09b45536741bd26 Mon Sep 17 00:00:00 2001 From: Trusted Computer <75872475+trustedcomputer@users.noreply.github.com> Date: Thu, 19 Feb 2026 09:10:18 -0800 Subject: [PATCH 122/279] feat: add chromium pdf generator support --- images/bench/Dockerfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/images/bench/Dockerfile b/images/bench/Dockerfile index 7591eec4..9c21345d 100644 --- a/images/bench/Dockerfile +++ b/images/bench/Dockerfile @@ -23,6 +23,8 @@ RUN apt-get update \ libharfbuzz0b \ libpangoft2-1.0-0 \ libpangocairo-1.0-0 \ + #Chromium + chromium-headless-shell \ # to work inside the container locales \ build-essential \ From 73edefc49d11da744e8f49e8c35906f7c34b9d68 Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 25 Feb 2026 07:01:07 +0000 Subject: [PATCH 123/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index e4dc5246..498fb537 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v16.6.1 +ERPNEXT_VERSION=v16.7.0 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index ab41e301..551c9344 100644 --- a/pwd.yml +++ b/pwd.yml @@ -1,6 +1,6 @@ services: backend: - image: frappe/erpnext:v16.6.1 + image: frappe/erpnext:v16.7.0 networks: - frappe_network deploy: @@ -16,7 +16,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v16.6.1 + image: frappe/erpnext:v16.7.0 networks: - frappe_network deploy: @@ -45,7 +45,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v16.6.1 + image: frappe/erpnext:v16.7.0 networks: - frappe_network deploy: @@ -100,7 +100,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v16.6.1 + image: frappe/erpnext:v16.7.0 networks: - frappe_network depends_on: @@ -126,7 +126,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v16.6.1 + image: frappe/erpnext:v16.7.0 networks: - frappe_network deploy: @@ -145,7 +145,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v16.6.1 + image: frappe/erpnext:v16.7.0 networks: - frappe_network deploy: @@ -182,7 +182,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v16.6.1 + image: frappe/erpnext:v16.7.0 networks: - frappe_network deploy: @@ -196,7 +196,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v16.6.1 + image: frappe/erpnext:v16.7.0 networks: - frappe_network deploy: From 4cac43fda3a52dc4915c9515c694dc078e09be05 Mon Sep 17 00:00:00 2001 From: github-actions Date: Thu, 26 Feb 2026 06:32:16 +0000 Subject: [PATCH 124/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 498fb537..b6408e70 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v16.7.0 +ERPNEXT_VERSION=v16.7.1 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index 551c9344..fb1f7dc3 100644 --- a/pwd.yml +++ b/pwd.yml @@ -1,6 +1,6 @@ services: backend: - image: frappe/erpnext:v16.7.0 + image: frappe/erpnext:v16.7.1 networks: - frappe_network deploy: @@ -16,7 +16,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v16.7.0 + image: frappe/erpnext:v16.7.1 networks: - frappe_network deploy: @@ -45,7 +45,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v16.7.0 + image: frappe/erpnext:v16.7.1 networks: - frappe_network deploy: @@ -100,7 +100,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v16.7.0 + image: frappe/erpnext:v16.7.1 networks: - frappe_network depends_on: @@ -126,7 +126,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v16.7.0 + image: frappe/erpnext:v16.7.1 networks: - frappe_network deploy: @@ -145,7 +145,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v16.7.0 + image: frappe/erpnext:v16.7.1 networks: - frappe_network deploy: @@ -182,7 +182,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v16.7.0 + image: frappe/erpnext:v16.7.1 networks: - frappe_network deploy: @@ -196,7 +196,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v16.7.0 + image: frappe/erpnext:v16.7.1 networks: - frappe_network deploy: From 4dd24f1fd06766e354ec4691c949ee252e320a27 Mon Sep 17 00:00:00 2001 From: github-actions Date: Thu, 26 Feb 2026 07:23:06 +0000 Subject: [PATCH 125/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index b6408e70..2baeee6a 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v16.7.1 +ERPNEXT_VERSION=v16.7.2 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index fb1f7dc3..d59bb22c 100644 --- a/pwd.yml +++ b/pwd.yml @@ -1,6 +1,6 @@ services: backend: - image: frappe/erpnext:v16.7.1 + image: frappe/erpnext:v16.7.2 networks: - frappe_network deploy: @@ -16,7 +16,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v16.7.1 + image: frappe/erpnext:v16.7.2 networks: - frappe_network deploy: @@ -45,7 +45,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v16.7.1 + image: frappe/erpnext:v16.7.2 networks: - frappe_network deploy: @@ -100,7 +100,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v16.7.1 + image: frappe/erpnext:v16.7.2 networks: - frappe_network depends_on: @@ -126,7 +126,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v16.7.1 + image: frappe/erpnext:v16.7.2 networks: - frappe_network deploy: @@ -145,7 +145,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v16.7.1 + image: frappe/erpnext:v16.7.2 networks: - frappe_network deploy: @@ -182,7 +182,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v16.7.1 + image: frappe/erpnext:v16.7.2 networks: - frappe_network deploy: @@ -196,7 +196,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v16.7.1 + image: frappe/erpnext:v16.7.2 networks: - frappe_network deploy: From 85aaca4bd5d5c46506d446158472ce7c4cb5b2c8 Mon Sep 17 00:00:00 2001 From: github-actions Date: Thu, 26 Feb 2026 08:57:12 +0000 Subject: [PATCH 126/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 2baeee6a..d932c8aa 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v16.7.2 +ERPNEXT_VERSION=v16.7.3 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index d59bb22c..b8d8543f 100644 --- a/pwd.yml +++ b/pwd.yml @@ -1,6 +1,6 @@ services: backend: - image: frappe/erpnext:v16.7.2 + image: frappe/erpnext:v16.7.3 networks: - frappe_network deploy: @@ -16,7 +16,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v16.7.2 + image: frappe/erpnext:v16.7.3 networks: - frappe_network deploy: @@ -45,7 +45,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v16.7.2 + image: frappe/erpnext:v16.7.3 networks: - frappe_network deploy: @@ -100,7 +100,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v16.7.2 + image: frappe/erpnext:v16.7.3 networks: - frappe_network depends_on: @@ -126,7 +126,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v16.7.2 + image: frappe/erpnext:v16.7.3 networks: - frappe_network deploy: @@ -145,7 +145,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v16.7.2 + image: frappe/erpnext:v16.7.3 networks: - frappe_network deploy: @@ -182,7 +182,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v16.7.2 + image: frappe/erpnext:v16.7.3 networks: - frappe_network deploy: @@ -196,7 +196,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v16.7.2 + image: frappe/erpnext:v16.7.3 networks: - frappe_network deploy: From 0ec329fe341bad36a9079083ce7da4a234d95705 Mon Sep 17 00:00:00 2001 From: Osama Shaikh <31347530+0samashaikh@users.noreply.github.com> Date: Tue, 3 Mar 2026 06:13:45 +0530 Subject: [PATCH 127/279] fix(nginx): forward correct proto/origin for socket.io behind proxy (#1817) --- resources/core/nginx/nginx-template.conf | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/resources/core/nginx/nginx-template.conf b/resources/core/nginx/nginx-template.conf index ded97c94..6ce77180 100644 --- a/resources/core/nginx/nginx-template.conf +++ b/resources/core/nginx/nginx-template.conf @@ -6,6 +6,12 @@ upstream socketio-server { server ${SOCKETIO} fail_timeout=0; } +# Parse the X-Forwarded-Proto header - if set - defaulting to $scheme. +map $http_x_forwarded_proto $proxy_x_forwarded_proto { + default $scheme; + https https; +} + server { listen 8080; server_name ${FRAPPE_SITE_NAME_HEADER}; @@ -36,10 +42,12 @@ server { location /socket.io { proxy_http_version 1.1; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header X-Frappe-Site-Name ${FRAPPE_SITE_NAME_HEADER}; - proxy_set_header Origin $scheme://$http_host; + proxy_set_header Origin $proxy_x_forwarded_proto://${FRAPPE_SITE_NAME_HEADER}; proxy_set_header Host $host; proxy_pass http://socketio-server; From 6e8384827fc7efb1f46779e95512e05dd810eaa8 Mon Sep 17 00:00:00 2001 From: Nishanth Abimanyu <119790219+nishanthabimanyu@users.noreply.github.com> Date: Tue, 3 Mar 2026 06:16:06 +0530 Subject: [PATCH 128/279] fix(bake): synchronize production build versions for v16 compliance (#1810) (#1823) * fix(bake): synchronize stable python 3.13 and node 22 to resolve issues #1810 and #1792 * fix(bake): update to python 3.14.2 and node 24.13.0 for v16 compliance per maintainer feedback --- docker-bake.hcl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-bake.hcl b/docker-bake.hcl index 9d3ccd00..baf7f3b3 100644 --- a/docker-bake.hcl +++ b/docker-bake.hcl @@ -6,10 +6,10 @@ variable "REGISTRY_USER" { } variable PYTHON_VERSION { - default = "3.11.6" + default = "3.14.2" } variable NODE_VERSION { - default = "20.19.2" + default = "24.13.0" } variable "FRAPPE_VERSION" { From 8070e5822e9de42c56928a2ce2996b14cbe2c6d5 Mon Sep 17 00:00:00 2001 From: Osama Shaikh <31347530+0samashaikh@users.noreply.github.com> Date: Tue, 3 Mar 2026 13:36:46 +0530 Subject: [PATCH 129/279] fix(nginx): use X-Forwarded-Proto for backend requests behind reverse proxy --- resources/core/nginx/nginx-template.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/core/nginx/nginx-template.conf b/resources/core/nginx/nginx-template.conf index 6ce77180..2e23f5fd 100644 --- a/resources/core/nginx/nginx-template.conf +++ b/resources/core/nginx/nginx-template.conf @@ -69,7 +69,7 @@ server { location @webserver { proxy_http_version 1.1; proxy_set_header X-Forwarded-For $remote_addr; - proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto; proxy_set_header X-Frappe-Site-Name ${FRAPPE_SITE_NAME_HEADER}; proxy_set_header Host $host; proxy_set_header X-Use-X-Accel-Redirect True; From c315c72eaa25591c82ca50d403c6127d2e6709cc Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 3 Mar 2026 18:24:24 +0000 Subject: [PATCH 130/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index d932c8aa..1ff9fbc7 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v16.7.3 +ERPNEXT_VERSION=v16.8.0 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index b8d8543f..b25b29bd 100644 --- a/pwd.yml +++ b/pwd.yml @@ -1,6 +1,6 @@ services: backend: - image: frappe/erpnext:v16.7.3 + image: frappe/erpnext:v16.8.0 networks: - frappe_network deploy: @@ -16,7 +16,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v16.7.3 + image: frappe/erpnext:v16.8.0 networks: - frappe_network deploy: @@ -45,7 +45,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v16.7.3 + image: frappe/erpnext:v16.8.0 networks: - frappe_network deploy: @@ -100,7 +100,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v16.7.3 + image: frappe/erpnext:v16.8.0 networks: - frappe_network depends_on: @@ -126,7 +126,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v16.7.3 + image: frappe/erpnext:v16.8.0 networks: - frappe_network deploy: @@ -145,7 +145,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v16.7.3 + image: frappe/erpnext:v16.8.0 networks: - frappe_network deploy: @@ -182,7 +182,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v16.7.3 + image: frappe/erpnext:v16.8.0 networks: - frappe_network deploy: @@ -196,7 +196,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v16.7.3 + image: frappe/erpnext:v16.8.0 networks: - frappe_network deploy: From 9dd00afc3ca9a11075ebbbff0c2a73aaf74121c5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Mar 2026 08:21:45 +0000 Subject: [PATCH 131/279] chore(deps): bump docker/setup-qemu-action from 3 to 4 Bumps [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) from 3 to 4. - [Release notes](https://github.com/docker/setup-qemu-action/releases) - [Commits](https://github.com/docker/setup-qemu-action/compare/v3...v4) --- updated-dependencies: - dependency-name: docker/setup-qemu-action dependency-version: '4' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/build_bench.yml | 2 +- .github/workflows/docker-build-push.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build_bench.yml b/.github/workflows/build_bench.yml index 48b4f818..1412c2b7 100644 --- a/.github/workflows/build_bench.yml +++ b/.github/workflows/build_bench.yml @@ -23,7 +23,7 @@ jobs: uses: actions/checkout@v6 - name: Setup QEMU - uses: docker/setup-qemu-action@v3 + uses: docker/setup-qemu-action@v4 with: image: tonistiigi/binfmt:latest platforms: all diff --git a/.github/workflows/docker-build-push.yml b/.github/workflows/docker-build-push.yml index a90f784e..e8b75521 100644 --- a/.github/workflows/docker-build-push.yml +++ b/.github/workflows/docker-build-push.yml @@ -46,7 +46,7 @@ jobs: uses: actions/checkout@v6 - name: Setup QEMU - uses: docker/setup-qemu-action@v3 + uses: docker/setup-qemu-action@v4 with: image: tonistiigi/binfmt:latest platforms: all From a122219d0ef1bb22a465a91d7dc3bcd60dc189d4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 5 Mar 2026 08:33:07 +0000 Subject: [PATCH 132/279] chore(deps): bump docker/login-action from 3 to 4 Bumps [docker/login-action](https://github.com/docker/login-action) from 3 to 4. - [Release notes](https://github.com/docker/login-action/releases) - [Commits](https://github.com/docker/login-action/compare/v3...v4) --- updated-dependencies: - dependency-name: docker/login-action dependency-version: '4' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/build_bench.yml | 2 +- .github/workflows/docker-build-push.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build_bench.yml b/.github/workflows/build_bench.yml index 48b4f818..13585a15 100644 --- a/.github/workflows/build_bench.yml +++ b/.github/workflows/build_bench.yml @@ -45,7 +45,7 @@ jobs: - name: Login if: ${{ github.repository == 'frappe/frappe_docker' && github.event_name != 'pull_request' }} - uses: docker/login-action@v3 + uses: docker/login-action@v4 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} diff --git a/.github/workflows/docker-build-push.yml b/.github/workflows/docker-build-push.yml index a90f784e..a57c05e6 100644 --- a/.github/workflows/docker-build-push.yml +++ b/.github/workflows/docker-build-push.yml @@ -88,7 +88,7 @@ jobs: - name: Login if: ${{ inputs.push }} - uses: docker/login-action@v3 + uses: docker/login-action@v4 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} From 6dd26933ccda61cdf3b829f946a731614de34599 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 5 Mar 2026 08:33:15 +0000 Subject: [PATCH 133/279] chore(deps): bump docker/setup-buildx-action from 3 to 4 Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 3 to 4. - [Release notes](https://github.com/docker/setup-buildx-action/releases) - [Commits](https://github.com/docker/setup-buildx-action/compare/v3...v4) --- updated-dependencies: - dependency-name: docker/setup-buildx-action dependency-version: '4' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/build_bench.yml | 2 +- .github/workflows/docker-build-push.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build_bench.yml b/.github/workflows/build_bench.yml index 48b4f818..865ee7e9 100644 --- a/.github/workflows/build_bench.yml +++ b/.github/workflows/build_bench.yml @@ -29,7 +29,7 @@ jobs: platforms: all - name: Setup Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@v4 - name: Set Environment Variables run: cat example.env | grep -o '^[^#]*' >> "$GITHUB_ENV" diff --git a/.github/workflows/docker-build-push.yml b/.github/workflows/docker-build-push.yml index a90f784e..edfe25d9 100644 --- a/.github/workflows/docker-build-push.yml +++ b/.github/workflows/docker-build-push.yml @@ -52,7 +52,7 @@ jobs: platforms: all - name: Setup Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@v4 with: driver-opts: network=host platforms: linux/${{ matrix.arch }} From 455ef1f725b99503e58140cd658a35a375611765 Mon Sep 17 00:00:00 2001 From: github-actions Date: Thu, 5 Mar 2026 12:26:28 +0000 Subject: [PATCH 134/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 1ff9fbc7..8a3c0078 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v16.8.0 +ERPNEXT_VERSION=v16.8.1 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index b25b29bd..2c415391 100644 --- a/pwd.yml +++ b/pwd.yml @@ -1,6 +1,6 @@ services: backend: - image: frappe/erpnext:v16.8.0 + image: frappe/erpnext:v16.8.1 networks: - frappe_network deploy: @@ -16,7 +16,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v16.8.0 + image: frappe/erpnext:v16.8.1 networks: - frappe_network deploy: @@ -45,7 +45,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v16.8.0 + image: frappe/erpnext:v16.8.1 networks: - frappe_network deploy: @@ -100,7 +100,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v16.8.0 + image: frappe/erpnext:v16.8.1 networks: - frappe_network depends_on: @@ -126,7 +126,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v16.8.0 + image: frappe/erpnext:v16.8.1 networks: - frappe_network deploy: @@ -145,7 +145,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v16.8.0 + image: frappe/erpnext:v16.8.1 networks: - frappe_network deploy: @@ -182,7 +182,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v16.8.0 + image: frappe/erpnext:v16.8.1 networks: - frappe_network deploy: @@ -196,7 +196,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v16.8.0 + image: frappe/erpnext:v16.8.1 networks: - frappe_network deploy: From b4e0501c3d0f6242eb149352c88644a5dc41b480 Mon Sep 17 00:00:00 2001 From: nishanthabimanyu Date: Fri, 6 Mar 2026 05:11:19 +0000 Subject: [PATCH 135/279] fix(overrides): update PostgreSQL to v15 and improve v16 compatibility --- overrides/compose.postgres.yaml | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/overrides/compose.postgres.yaml b/overrides/compose.postgres.yaml index 433ca71a..2d8e7876 100644 --- a/overrides/compose.postgres.yaml +++ b/overrides/compose.postgres.yaml @@ -2,13 +2,29 @@ services: configurator: environment: DB_HOST: db - DB_PORT: 5432 + DB_PORT: "5432" + DB_TYPE: postgres + command: + - > + ls -1 apps > sites/apps.txt; + bench set-config -g db_type postgres; + bench set-config -g db_host $$DB_HOST; + bench set-config -gp db_port $$DB_PORT; + bench set-config -g redis_cache "redis://$$REDIS_CACHE"; + bench set-config -g redis_queue "redis://$$REDIS_QUEUE"; + bench set-config -g redis_socketio "redis://$$REDIS_QUEUE"; + bench set-config -gp socketio_port $$SOCKETIO_PORT; + bench set-config -g chromium_path /usr/bin/chromium-headless-shell; depends_on: - - db + db: + condition: service_healthy db: - image: postgres:13.5 - command: [] + image: postgres:15-alpine + healthcheck: + test: ["CMD-SHELL", "pg_isready -U postgres"] + interval: 5s + retries: 5 environment: POSTGRES_PASSWORD: ${DB_PASSWORD:?No db password set} volumes: From bf1f08797d87dd47ef27db311e2a31a45d6083bd Mon Sep 17 00:00:00 2001 From: nishanthabimanyu Date: Fri, 6 Mar 2026 05:30:02 +0000 Subject: [PATCH 136/279] fix(overrides): use default DB_PASSWORD to fix CI failures --- overrides/compose.postgres.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/overrides/compose.postgres.yaml b/overrides/compose.postgres.yaml index 2d8e7876..5d36cd64 100644 --- a/overrides/compose.postgres.yaml +++ b/overrides/compose.postgres.yaml @@ -26,7 +26,7 @@ services: interval: 5s retries: 5 environment: - POSTGRES_PASSWORD: ${DB_PASSWORD:?No db password set} + POSTGRES_PASSWORD: ${DB_PASSWORD:-postgres} volumes: - db-data:/var/lib/postgresql/data From 47ac9e8422b5b9861873eeed5f0eeaa95d40008d Mon Sep 17 00:00:00 2001 From: nishanthabimanyu Date: Fri, 6 Mar 2026 05:40:47 +0000 Subject: [PATCH 137/279] fix(overrides): simplify postgres override and use consistent default password --- overrides/compose.postgres.yaml | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/overrides/compose.postgres.yaml b/overrides/compose.postgres.yaml index 5d36cd64..18d23feb 100644 --- a/overrides/compose.postgres.yaml +++ b/overrides/compose.postgres.yaml @@ -3,18 +3,6 @@ services: environment: DB_HOST: db DB_PORT: "5432" - DB_TYPE: postgres - command: - - > - ls -1 apps > sites/apps.txt; - bench set-config -g db_type postgres; - bench set-config -g db_host $$DB_HOST; - bench set-config -gp db_port $$DB_PORT; - bench set-config -g redis_cache "redis://$$REDIS_CACHE"; - bench set-config -g redis_queue "redis://$$REDIS_QUEUE"; - bench set-config -g redis_socketio "redis://$$REDIS_QUEUE"; - bench set-config -gp socketio_port $$SOCKETIO_PORT; - bench set-config -g chromium_path /usr/bin/chromium-headless-shell; depends_on: db: condition: service_healthy @@ -26,7 +14,7 @@ services: interval: 5s retries: 5 environment: - POSTGRES_PASSWORD: ${DB_PASSWORD:-postgres} + POSTGRES_PASSWORD: ${DB_PASSWORD:-123} volumes: - db-data:/var/lib/postgresql/data From 9c777a56e5da554b3a46b0cfbdd006c12e474015 Mon Sep 17 00:00:00 2001 From: nishanthabimanyu Date: Fri, 6 Mar 2026 06:03:56 +0000 Subject: [PATCH 138/279] fix(overrides): clear db command for postgres to fix CI merge conflicts --- overrides/compose.postgres.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/overrides/compose.postgres.yaml b/overrides/compose.postgres.yaml index 18d23feb..b3222f6b 100644 --- a/overrides/compose.postgres.yaml +++ b/overrides/compose.postgres.yaml @@ -9,6 +9,7 @@ services: db: image: postgres:15-alpine + command: [] healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres"] interval: 5s From ee4aaee2ae5617631910283a0e0c9e6ebcb06bf8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Mar 2026 08:22:24 +0000 Subject: [PATCH 139/279] chore(deps): bump docker/bake-action from 6.10.0 to 7.0.0 Bumps [docker/bake-action](https://github.com/docker/bake-action) from 6.10.0 to 7.0.0. - [Release notes](https://github.com/docker/bake-action/releases) - [Commits](https://github.com/docker/bake-action/compare/v6.10.0...v7.0.0) --- updated-dependencies: - dependency-name: docker/bake-action dependency-version: 7.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/build_bench.yml | 4 ++-- .github/workflows/docker-build-push.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build_bench.yml b/.github/workflows/build_bench.yml index 57ee9279..257a31c1 100644 --- a/.github/workflows/build_bench.yml +++ b/.github/workflows/build_bench.yml @@ -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.10.0 + uses: docker/bake-action@v7.0.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.10.0 + uses: docker/bake-action@v7.0.0 with: targets: bench push: true diff --git a/.github/workflows/docker-build-push.yml b/.github/workflows/docker-build-push.yml index 973e7f18..376118cd 100644 --- a/.github/workflows/docker-build-push.yml +++ b/.github/workflows/docker-build-push.yml @@ -66,7 +66,7 @@ jobs: echo "NODE_VERSION=${{ inputs.node_version }}" >> "$GITHUB_ENV" - name: Build - uses: docker/bake-action@v6.10.0 + uses: docker/bake-action@v7.0.0 with: source: . push: true @@ -95,7 +95,7 @@ jobs: - name: Push if: ${{ inputs.push }} - uses: docker/bake-action@v6.10.0 + uses: docker/bake-action@v7.0.0 with: push: true set: "*.platform=linux/amd64,linux/arm64" From 09ce533de1f4d9b84649b083e25e4cad4b03a17c Mon Sep 17 00:00:00 2001 From: github-actions Date: Fri, 6 Mar 2026 09:05:35 +0000 Subject: [PATCH 140/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 8a3c0078..5cd92c6e 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v16.8.1 +ERPNEXT_VERSION=v16.8.2 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index 2c415391..5ec9e9e8 100644 --- a/pwd.yml +++ b/pwd.yml @@ -1,6 +1,6 @@ services: backend: - image: frappe/erpnext:v16.8.1 + image: frappe/erpnext:v16.8.2 networks: - frappe_network deploy: @@ -16,7 +16,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v16.8.1 + image: frappe/erpnext:v16.8.2 networks: - frappe_network deploy: @@ -45,7 +45,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v16.8.1 + image: frappe/erpnext:v16.8.2 networks: - frappe_network deploy: @@ -100,7 +100,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v16.8.1 + image: frappe/erpnext:v16.8.2 networks: - frappe_network depends_on: @@ -126,7 +126,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v16.8.1 + image: frappe/erpnext:v16.8.2 networks: - frappe_network deploy: @@ -145,7 +145,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v16.8.1 + image: frappe/erpnext:v16.8.2 networks: - frappe_network deploy: @@ -182,7 +182,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v16.8.1 + image: frappe/erpnext:v16.8.2 networks: - frappe_network deploy: @@ -196,7 +196,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v16.8.1 + image: frappe/erpnext:v16.8.2 networks: - frappe_network deploy: From 15648342ddbf6a3f20f3e22e4e1e5a1f162f8739 Mon Sep 17 00:00:00 2001 From: nishanthabimanyu Date: Mon, 9 Mar 2026 16:17:43 +0000 Subject: [PATCH 141/279] docs(postgres): add migration guide and update to postgres 15.17 --- docs/04-operations/01-site-operations.md | 13 ++---- .../03-postgres-major-version-upgrade.md | 40 +++++++++++++++++++ overrides/compose.postgres.yaml | 2 +- 3 files changed, 45 insertions(+), 10 deletions(-) create mode 100644 docs/06-migration/03-postgres-major-version-upgrade.md diff --git a/docs/04-operations/01-site-operations.md b/docs/04-operations/01-site-operations.md index 1520d6aa..6f20a332 100644 --- a/docs/04-operations/01-site-operations.md +++ b/docs/04-operations/01-site-operations.md @@ -15,17 +15,12 @@ docker-compose exec backend bench new-site --mariadb-user-host-login-scope=% --d If you need to install some app, specify `--install-app`. To see all options, just run `bench new-site --help`. -To create Postgres site (assuming you already use [Postgres compose override](../02-setup/05-overrides.md)) you need have to do set `root_login` and `root_password` in common config before that: +To create a Postgres site (assuming you already use [Postgres compose override](../02-setup/05-overrides.md)), the `root_login` and `root_password` are now automatically set by the `configurator`. For major version upgrades, please refer to the [Postgres Migration Guide](../06-migration/03-postgres-major-version-upgrade.md). + +To create a new Postgres site: ```sh -docker-compose exec backend bench set-config -g root_login -docker-compose exec backend bench set-config -g root_password -``` - -Also command is slightly different: - -```sh -docker-compose exec backend bench new-site --mariadb-user-host-login-scope=% --db-type postgres --admin-password +docker-compose exec backend bench new-site --db-type postgres --admin-password ``` ## Push backup to S3 storage diff --git a/docs/06-migration/03-postgres-major-version-upgrade.md b/docs/06-migration/03-postgres-major-version-upgrade.md new file mode 100644 index 00000000..d6339f93 --- /dev/null +++ b/docs/06-migration/03-postgres-major-version-upgrade.md @@ -0,0 +1,40 @@ +# PostgreSQL Major Version Upgrade (v13 to v15) + +Upgrading PostgreSQL from version 13 to 15 is a major version jump. Since PostgreSQL does not support in-place data directory upgrades, existing users must manually migrate their data using `pg_dump`. + +### **Migration Steps** + +1. **Backup Existing Data (Version 13):** + Before updating your compose file, ensure your containers are running and perform a dump of all databases. + ```bash + docker exec -it -db-1 pg_dumpall -U postgres > full_dump.sql + ``` + +2. **Stop and Remove Containers:** + ```bash + docker compose down + ``` + +3. **Delete Old Data Volume:** + PostgreSQL 15 cannot read data created by version 13. You must remove the existing volume (Warning: this deletes the old data directory). + ```bash + docker volume rm _db-data + ``` + +4. **Update Image and Start (Version 15):** + Update your `overrides/compose.postgres.yaml` (or pull the latest changes) and start the containers. + ```bash + docker compose up -d + ``` + +5. **Restore Data:** + Restore the dump into the new PostgreSQL 15 instance. + ```bash + cat full_dump.sql | docker exec -i -db-1 psql -U postgres + ``` + +6. **Verify and Clean Up:** + Ensure your sites are working correctly with `bench migrate` and then remove the `full_dump.sql` file. + ```bash + docker exec -it -backend-1 bench --site all migrate + ``` diff --git a/overrides/compose.postgres.yaml b/overrides/compose.postgres.yaml index b3222f6b..376758f8 100644 --- a/overrides/compose.postgres.yaml +++ b/overrides/compose.postgres.yaml @@ -8,7 +8,7 @@ services: condition: service_healthy db: - image: postgres:15-alpine + image: postgres:15.17 command: [] healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres"] From 5191d1965de6aa598cac58d96159059cf577661f Mon Sep 17 00:00:00 2001 From: nishanthabimanyu Date: Tue, 10 Mar 2026 03:50:02 +0000 Subject: [PATCH 142/279] style: fix prettier formatting for postgres migration guide --- docs/06-migration/03-postgres-major-version-upgrade.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/06-migration/03-postgres-major-version-upgrade.md b/docs/06-migration/03-postgres-major-version-upgrade.md index d6339f93..b20b94bb 100644 --- a/docs/06-migration/03-postgres-major-version-upgrade.md +++ b/docs/06-migration/03-postgres-major-version-upgrade.md @@ -6,29 +6,34 @@ Upgrading PostgreSQL from version 13 to 15 is a major version jump. Since Postgr 1. **Backup Existing Data (Version 13):** Before updating your compose file, ensure your containers are running and perform a dump of all databases. + ```bash docker exec -it -db-1 pg_dumpall -U postgres > full_dump.sql ``` 2. **Stop and Remove Containers:** + ```bash docker compose down ``` 3. **Delete Old Data Volume:** PostgreSQL 15 cannot read data created by version 13. You must remove the existing volume (Warning: this deletes the old data directory). + ```bash docker volume rm _db-data ``` 4. **Update Image and Start (Version 15):** Update your `overrides/compose.postgres.yaml` (or pull the latest changes) and start the containers. + ```bash docker compose up -d ``` 5. **Restore Data:** Restore the dump into the new PostgreSQL 15 instance. + ```bash cat full_dump.sql | docker exec -i -db-1 psql -U postgres ``` From 9a5f17f09bdb781c7d4b70ee4f45d12ced942170 Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 10 Mar 2026 07:13:59 +0000 Subject: [PATCH 143/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 5cd92c6e..bc45a5bc 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v16.8.2 +ERPNEXT_VERSION=v16.8.3 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index 5ec9e9e8..bce456ff 100644 --- a/pwd.yml +++ b/pwd.yml @@ -1,6 +1,6 @@ services: backend: - image: frappe/erpnext:v16.8.2 + image: frappe/erpnext:v16.8.3 networks: - frappe_network deploy: @@ -16,7 +16,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v16.8.2 + image: frappe/erpnext:v16.8.3 networks: - frappe_network deploy: @@ -45,7 +45,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v16.8.2 + image: frappe/erpnext:v16.8.3 networks: - frappe_network deploy: @@ -100,7 +100,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v16.8.2 + image: frappe/erpnext:v16.8.3 networks: - frappe_network depends_on: @@ -126,7 +126,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v16.8.2 + image: frappe/erpnext:v16.8.3 networks: - frappe_network deploy: @@ -145,7 +145,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v16.8.2 + image: frappe/erpnext:v16.8.3 networks: - frappe_network deploy: @@ -182,7 +182,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v16.8.2 + image: frappe/erpnext:v16.8.3 networks: - frappe_network deploy: @@ -196,7 +196,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v16.8.2 + image: frappe/erpnext:v16.8.3 networks: - frappe_network deploy: From d6045cc9badf8b2bd4cc9fadd9d52769a4648459 Mon Sep 17 00:00:00 2001 From: IB2357 Date: Tue, 10 Mar 2026 15:09:26 +0300 Subject: [PATCH 144/279] fix(overrides): remove redis services from mariadb network in multi-bench setup --- overrides/compose.multi-bench.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/overrides/compose.multi-bench.yaml b/overrides/compose.multi-bench.yaml index d499686b..e457dd19 100644 --- a/overrides/compose.multi-bench.yaml +++ b/overrides/compose.multi-bench.yaml @@ -37,12 +37,10 @@ services: redis-cache: networks: - bench-network - - mariadb-network redis-queue: networks: - bench-network - - mariadb-network networks: traefik-public: From 91a190e92406c017e4160c78d22e5c37aea19523 Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 10 Mar 2026 15:16:05 +0000 Subject: [PATCH 145/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index bc45a5bc..25e8be69 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v16.8.3 +ERPNEXT_VERSION=v16.9.0 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index bce456ff..63265094 100644 --- a/pwd.yml +++ b/pwd.yml @@ -1,6 +1,6 @@ services: backend: - image: frappe/erpnext:v16.8.3 + image: frappe/erpnext:v16.9.0 networks: - frappe_network deploy: @@ -16,7 +16,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v16.8.3 + image: frappe/erpnext:v16.9.0 networks: - frappe_network deploy: @@ -45,7 +45,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v16.8.3 + image: frappe/erpnext:v16.9.0 networks: - frappe_network deploy: @@ -100,7 +100,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v16.8.3 + image: frappe/erpnext:v16.9.0 networks: - frappe_network depends_on: @@ -126,7 +126,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v16.8.3 + image: frappe/erpnext:v16.9.0 networks: - frappe_network deploy: @@ -145,7 +145,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v16.8.3 + image: frappe/erpnext:v16.9.0 networks: - frappe_network deploy: @@ -182,7 +182,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v16.8.3 + image: frappe/erpnext:v16.9.0 networks: - frappe_network deploy: @@ -196,7 +196,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v16.8.3 + image: frappe/erpnext:v16.9.0 networks: - frappe_network deploy: From 904df21d43a24248092b9cbcbe230221591360ad Mon Sep 17 00:00:00 2001 From: RinZ27 <222222878+RinZ27@users.noreply.github.com> Date: Wed, 11 Mar 2026 21:43:18 +0700 Subject: [PATCH 146/279] Fix Nginx header inheritance for /files location --- resources/core/nginx/nginx-template.conf | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/resources/core/nginx/nginx-template.conf b/resources/core/nginx/nginx-template.conf index 2e23f5fd..8aaf0782 100644 --- a/resources/core/nginx/nginx-template.conf +++ b/resources/core/nginx/nginx-template.conf @@ -21,11 +21,11 @@ server { proxy_buffers 4 256k; proxy_busy_buffers_size 256k; - add_header X-Frame-Options "SAMEORIGIN"; - add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"; - add_header X-Content-Type-Options nosniff; - add_header X-XSS-Protection "1; mode=block"; - add_header Referrer-Policy "same-origin, strict-origin-when-cross-origin"; + add_header X-Frame-Options "SAMEORIGIN" always; + add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always; + add_header X-Content-Type-Options nosniff always; + add_header X-XSS-Protection "1; mode=block" always; + add_header Referrer-Policy "same-origin, strict-origin-when-cross-origin" always; set_real_ip_from ${UPSTREAM_REAL_IP_ADDRESS}; real_ip_header ${UPSTREAM_REAL_IP_HEADER}; @@ -59,6 +59,11 @@ server { rewrite ^(.+)\.html$ $1 permanent; location ~ ^/files/.*.(htm|html|svg|xml) { + add_header X-Frame-Options "SAMEORIGIN" always; + add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always; + add_header X-Content-Type-Options nosniff always; + add_header X-XSS-Protection "1; mode=block" always; + add_header Referrer-Policy "same-origin, strict-origin-when-cross-origin" always; add_header Content-disposition "attachment"; try_files /${FRAPPE_SITE_NAME_HEADER}/public/$uri @webserver; } From ad9d95d3777eb7d83d09be8e2eff2f72df030820 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 12 Mar 2026 08:23:02 +0000 Subject: [PATCH 147/279] chore(deps): bump webfactory/ssh-agent from 0.9.1 to 0.10.0 Bumps [webfactory/ssh-agent](https://github.com/webfactory/ssh-agent) from 0.9.1 to 0.10.0. - [Release notes](https://github.com/webfactory/ssh-agent/releases) - [Changelog](https://github.com/webfactory/ssh-agent/blob/master/CHANGELOG.md) - [Commits](https://github.com/webfactory/ssh-agent/compare/v0.9.1...v0.10.0) --- updated-dependencies: - dependency-name: webfactory/ssh-agent dependency-version: 0.10.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/build_stable.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_stable.yml b/.github/workflows/build_stable.yml index 6f0535d1..174516bc 100644 --- a/.github/workflows/build_stable.yml +++ b/.github/workflows/build_stable.yml @@ -100,7 +100,7 @@ jobs: steps: - name: Setup deploy key - uses: webfactory/ssh-agent@v0.9.1 + uses: webfactory/ssh-agent@v0.10.0 with: ssh-private-key: ${{ secrets.HELM_DEPLOY_KEY }} From 7228b5005cff48c916e1df9cfdf4760451894a43 Mon Sep 17 00:00:00 2001 From: github-actions Date: Sun, 15 Mar 2026 08:49:55 +0000 Subject: [PATCH 148/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 25e8be69..706243ac 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v16.9.0 +ERPNEXT_VERSION=v16.9.1 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index 63265094..865a7af0 100644 --- a/pwd.yml +++ b/pwd.yml @@ -1,6 +1,6 @@ services: backend: - image: frappe/erpnext:v16.9.0 + image: frappe/erpnext:v16.9.1 networks: - frappe_network deploy: @@ -16,7 +16,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v16.9.0 + image: frappe/erpnext:v16.9.1 networks: - frappe_network deploy: @@ -45,7 +45,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v16.9.0 + image: frappe/erpnext:v16.9.1 networks: - frappe_network deploy: @@ -100,7 +100,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v16.9.0 + image: frappe/erpnext:v16.9.1 networks: - frappe_network depends_on: @@ -126,7 +126,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v16.9.0 + image: frappe/erpnext:v16.9.1 networks: - frappe_network deploy: @@ -145,7 +145,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v16.9.0 + image: frappe/erpnext:v16.9.1 networks: - frappe_network deploy: @@ -182,7 +182,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v16.9.0 + image: frappe/erpnext:v16.9.1 networks: - frappe_network deploy: @@ -196,7 +196,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v16.9.0 + image: frappe/erpnext:v16.9.1 networks: - frappe_network deploy: From e7f2c66e1d22912660463ec293a73238847fe5b3 Mon Sep 17 00:00:00 2001 From: adithya Date: Fri, 5 Dec 2025 23:48:03 +0530 Subject: [PATCH 149/279] feat: VitePress for docs VitePress is configured in the repo for handling docs --- .gitignore | 4 + docs/.vitepress/config.mts | 27 + docs/01-getting-started/03-arm64.md | 4 + .../04-single-compose-setup.md | 4 + docs/01-getting-started/index.md | 3 + docs/02-setup/01-overview.md | 4 + docs/02-setup/02-build-setup.md | 4 + docs/02-setup/03-start-setup.md | 4 + docs/02-setup/04-env-variables.md | 4 + docs/02-setup/05-overrides.md | 4 + docs/02-setup/06-setup-examples.md | 4 + docs/02-setup/07-single-server-example.md | 4 + docs/02-setup/index.md | 3 + docs/03-production/01-tls-ssl-setup.md | 6 +- docs/03-production/02-backup-strategy.md | 4 + docs/03-production/03-multi-tenancy.md | 4 + docs/03-production/index.md | 3 + docs/04-operations/01-site-operations.md | 4 + docs/04-operations/index.md | 3 + docs/05-development/01-development.md | 4 + docs/05-development/02-debugging.md | 4 + .../03-local-services-connection.md | 4 + docs/05-development/index.md | 3 + .../01-migrate-from-multi-image-setup.md | 4 + docs/06-migration/index.md | 3 + docs/07-troubleshooting/01-troubleshoot.md | 11 +- .../02-windows-nginx-entrypoint-error.md | 4 + docs/07-troubleshooting/index.md | 3 + .../01-build-version-10-images.md | 4 + docs/08-reference/index.md | 3 + docs/getting-started.md | 4 + docs/images/frappe_docker.png | Bin 0 -> 45163 bytes docs/index.md | 26 + package.json | 11 + pnpm-lock.yaml | 1756 +++++++++++++++++ 35 files changed, 1937 insertions(+), 4 deletions(-) create mode 100644 docs/.vitepress/config.mts create mode 100644 docs/01-getting-started/index.md create mode 100644 docs/02-setup/index.md create mode 100644 docs/03-production/index.md create mode 100644 docs/04-operations/index.md create mode 100644 docs/05-development/index.md create mode 100644 docs/06-migration/index.md create mode 100644 docs/07-troubleshooting/index.md create mode 100644 docs/08-reference/index.md create mode 100644 docs/images/frappe_docker.png create mode 100644 docs/index.md create mode 100644 package.json create mode 100644 pnpm-lock.yaml diff --git a/.gitignore b/.gitignore index 94a9fe2f..4704f2d6 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,7 @@ venv # NodeJS node_modules + +# VitePress +**/.vitepress/dist +**/.vitepress/cache \ No newline at end of file diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts new file mode 100644 index 00000000..316d9829 --- /dev/null +++ b/docs/.vitepress/config.mts @@ -0,0 +1,27 @@ +import { defineConfig } from "vitepress"; +import { withSidebar } from "vitepress-sidebar"; + +// https://vitepress.dev/reference/site-config +const vitePressOptions = { + title: "Frappe Docker Docs", + description: "Frappe in a Container", + themeConfig: { + logo: "../images/frappe_docker.png", + // https://vitepress.dev/reference/default-theme-config + nav: [{ text: "Home", link: "/" }], + + socialLinks: [ + { icon: "github", link: "https://github.com/frappe/frappe_docker/" }, + ], + }, +}; + +const vitePressSidebarOptions = { + documentRootPath: "./docs", + useTitleFromFrontmatter: true, + useFolderTitleFromIndexFile: true, +}; + +export default defineConfig( + withSidebar(vitePressOptions, vitePressSidebarOptions) +); diff --git a/docs/01-getting-started/03-arm64.md b/docs/01-getting-started/03-arm64.md index d2c50ce0..c76beb06 100644 --- a/docs/01-getting-started/03-arm64.md +++ b/docs/01-getting-started/03-arm64.md @@ -1,3 +1,7 @@ +--- +title: Quick Start with Linux and Mac +--- + # How to install ERPNext on linux/mac using Frappe_docker ? ## Clone the repo diff --git a/docs/01-getting-started/04-single-compose-setup.md b/docs/01-getting-started/04-single-compose-setup.md index aea2914c..72e71474 100644 --- a/docs/01-getting-started/04-single-compose-setup.md +++ b/docs/01-getting-started/04-single-compose-setup.md @@ -1,3 +1,7 @@ +--- +title: Single Compose Setup +--- + # Single Compose Setup This setup is a very simple single compose file that does everything to start required services and a frappe-bench. It is used to start play with docker instance with a site. The file is located in the root of repo and named `pwd.yml`. diff --git a/docs/01-getting-started/index.md b/docs/01-getting-started/index.md new file mode 100644 index 00000000..f15cbd37 --- /dev/null +++ b/docs/01-getting-started/index.md @@ -0,0 +1,3 @@ +--- +title: Getting Started +--- diff --git a/docs/02-setup/01-overview.md b/docs/02-setup/01-overview.md index 08f3d233..bfae92cf 100644 --- a/docs/02-setup/01-overview.md +++ b/docs/02-setup/01-overview.md @@ -1,3 +1,7 @@ +--- +title: Setup Overview +--- + The purpose of this document is to give you an overview of how the Frappe Docker containers are structured. # 🐳 Images diff --git a/docs/02-setup/02-build-setup.md b/docs/02-setup/02-build-setup.md index 6c0c49da..93331280 100644 --- a/docs/02-setup/02-build-setup.md +++ b/docs/02-setup/02-build-setup.md @@ -1,3 +1,7 @@ +--- +title: Build Setup +--- + This guide walks you through building Frappe images from the repository resources. # Prerequisites diff --git a/docs/02-setup/03-start-setup.md b/docs/02-setup/03-start-setup.md index bbcb1258..93bd6391 100644 --- a/docs/02-setup/03-start-setup.md +++ b/docs/02-setup/03-start-setup.md @@ -1,3 +1,7 @@ +--- +title: Start Container +--- + # start Container Once your compose file is ready, start all containers with a single command: diff --git a/docs/02-setup/04-env-variables.md b/docs/02-setup/04-env-variables.md index 54ed2956..ab07da67 100644 --- a/docs/02-setup/04-env-variables.md +++ b/docs/02-setup/04-env-variables.md @@ -1,3 +1,7 @@ +--- +title: Environment Variables +--- + # Environment Variables Reference Environment variables configure your Frappe Docker setup. They can be set directly in the container or defined in a `.env` file referenced by Docker Compose. diff --git a/docs/02-setup/05-overrides.md b/docs/02-setup/05-overrides.md index 0d7b6004..c81bf153 100644 --- a/docs/02-setup/05-overrides.md +++ b/docs/02-setup/05-overrides.md @@ -1,3 +1,7 @@ +--- +title: Overrides +--- + Overrides extend the base compose.yaml with additional services or modify existing behavior. Include them in your compose command using multiple -f flags. ```bash diff --git a/docs/02-setup/06-setup-examples.md b/docs/02-setup/06-setup-examples.md index 5d9b569a..02c5f3c6 100644 --- a/docs/02-setup/06-setup-examples.md +++ b/docs/02-setup/06-setup-examples.md @@ -1,3 +1,7 @@ +--- +title: Setup Examples +--- + # Setup Examples This guide provides practical examples for common setup scenarios. These examples build upon the [container setup guide](01-overview.md) and demonstrate how to combine the base compose file with overrides. diff --git a/docs/02-setup/07-single-server-example.md b/docs/02-setup/07-single-server-example.md index 6827dda6..fd4e1130 100644 --- a/docs/02-setup/07-single-server-example.md +++ b/docs/02-setup/07-single-server-example.md @@ -1,3 +1,7 @@ +--- +title: Single Server Setup +--- + # Single Server Example This guide demonstrates setting up multiple Frappe/ERPNext benches (projects) on a single server with shared infrastructure components. diff --git a/docs/02-setup/index.md b/docs/02-setup/index.md new file mode 100644 index 00000000..0e51640f --- /dev/null +++ b/docs/02-setup/index.md @@ -0,0 +1,3 @@ +--- +title: Setup +--- diff --git a/docs/03-production/01-tls-ssl-setup.md b/docs/03-production/01-tls-ssl-setup.md index b88fc8c1..e2ea2e0e 100644 --- a/docs/03-production/01-tls-ssl-setup.md +++ b/docs/03-production/01-tls-ssl-setup.md @@ -1,4 +1,8 @@ -# TLS/SSL Setup Overview +--- +title: TLS/SSL Setup Overview +--- + +# Accessing ERPNext through https on local deployment Frappe Docker supports multiple TLS/SSL approaches. Choose the one that matches your routing needs and where you want the proxy to run. diff --git a/docs/03-production/02-backup-strategy.md b/docs/03-production/02-backup-strategy.md index ce5d8b49..bba20b29 100644 --- a/docs/03-production/02-backup-strategy.md +++ b/docs/03-production/02-backup-strategy.md @@ -1,3 +1,7 @@ +--- +title: Backup Strategy +--- + Create backup service or stack. ```yaml diff --git a/docs/03-production/03-multi-tenancy.md b/docs/03-production/03-multi-tenancy.md index 2f469bfd..4551da3e 100644 --- a/docs/03-production/03-multi-tenancy.md +++ b/docs/03-production/03-multi-tenancy.md @@ -1,3 +1,7 @@ +--- +title: Multi Tenancy +--- + WARNING: Do not use this in production if the site is going to be served over plain http. ### Step 1 diff --git a/docs/03-production/index.md b/docs/03-production/index.md new file mode 100644 index 00000000..2d4b91a5 --- /dev/null +++ b/docs/03-production/index.md @@ -0,0 +1,3 @@ +--- +title: Production +--- diff --git a/docs/04-operations/01-site-operations.md b/docs/04-operations/01-site-operations.md index 1520d6aa..ac8fc957 100644 --- a/docs/04-operations/01-site-operations.md +++ b/docs/04-operations/01-site-operations.md @@ -1,3 +1,7 @@ +--- +title: Site Operations +--- + # Site operations > πŸ’‘ You should setup `--project-name` option in `docker-compose` commands if you have non-standard project name. diff --git a/docs/04-operations/index.md b/docs/04-operations/index.md new file mode 100644 index 00000000..eb2b7cf5 --- /dev/null +++ b/docs/04-operations/index.md @@ -0,0 +1,3 @@ +--- +title: Operations +--- diff --git a/docs/05-development/01-development.md b/docs/05-development/01-development.md index 6ff718e9..99df7254 100644 --- a/docs/05-development/01-development.md +++ b/docs/05-development/01-development.md @@ -1,3 +1,7 @@ +--- +title: Getting Started +--- + # Getting Started ## Prerequisites diff --git a/docs/05-development/02-debugging.md b/docs/05-development/02-debugging.md index d506be0f..e5ad13a0 100644 --- a/docs/05-development/02-debugging.md +++ b/docs/05-development/02-debugging.md @@ -1,3 +1,7 @@ +--- +title: Debugging +--- + Add the following configuration to `launch.json` `configurations` array to start bench console and use debugger. Replace `development.localhost` with appropriate site. Also replace `frappe-bench` with name of the bench directory. ```json diff --git a/docs/05-development/03-local-services-connection.md b/docs/05-development/03-local-services-connection.md index c76b52a2..69186b35 100644 --- a/docs/05-development/03-local-services-connection.md +++ b/docs/05-development/03-local-services-connection.md @@ -1,3 +1,7 @@ +--- +title: Local Services +--- + Add following to frappe container from the `.devcontainer/docker-compose.yml`: ```yaml diff --git a/docs/05-development/index.md b/docs/05-development/index.md new file mode 100644 index 00000000..4cb3f607 --- /dev/null +++ b/docs/05-development/index.md @@ -0,0 +1,3 @@ +--- +title: Development +--- diff --git a/docs/06-migration/01-migrate-from-multi-image-setup.md b/docs/06-migration/01-migrate-from-multi-image-setup.md index 77202e0f..0fd2e344 100644 --- a/docs/06-migration/01-migrate-from-multi-image-setup.md +++ b/docs/06-migration/01-migrate-from-multi-image-setup.md @@ -1,3 +1,7 @@ +--- +title: Migrate from Multi Image Setup +--- + ## Migrate from multi-image setup All the containers now use same image. Use `frappe/erpnext` instead of `frappe/frappe-worker`, `frappe/frappe-nginx` , `frappe/frappe-socketio` , `frappe/erpnext-worker` and `frappe/erpnext-nginx`. diff --git a/docs/06-migration/index.md b/docs/06-migration/index.md new file mode 100644 index 00000000..8083bf82 --- /dev/null +++ b/docs/06-migration/index.md @@ -0,0 +1,3 @@ +--- +title: Migration +--- diff --git a/docs/07-troubleshooting/01-troubleshoot.md b/docs/07-troubleshooting/01-troubleshoot.md index 09d7f8b6..d2254b8c 100644 --- a/docs/07-troubleshooting/01-troubleshoot.md +++ b/docs/07-troubleshooting/01-troubleshoot.md @@ -1,6 +1,11 @@ -1. [Fixing MariaDB issues after rebuilding the container](#fixing-mariadb-issues-after-rebuilding-the-container) -1. [docker-compose does not recognize variables from `.env` file](#docker-compose-does-not-recognize-variables-from-env-file) -1. [Windows Based Installation](#windows-based-installation) +--- +title: Troubleshoot +--- + +- [Fixing MariaDB issues after rebuilding the container](#fixing-mariadb-issues-after-rebuilding-the-container) +- [docker-compose does not recognize variables from `.env` file](#docker-compose-does-not-recognize-variables-from-env-file) +- [Windows Based Installation](#windows-based-installation) +- [Redo installation](#redo-installation) ### Fixing MariaDB issues after rebuilding the container diff --git a/docs/07-troubleshooting/02-windows-nginx-entrypoint-error.md b/docs/07-troubleshooting/02-windows-nginx-entrypoint-error.md index 112ed0ea..a2bbdb34 100644 --- a/docs/07-troubleshooting/02-windows-nginx-entrypoint-error.md +++ b/docs/07-troubleshooting/02-windows-nginx-entrypoint-error.md @@ -1,3 +1,7 @@ +--- +title: NGINX in Windows +--- + # Resolving Docker `nginx-entrypoint.sh` Script Not Found Error on Windows If you're encountering the error `exec /usr/local/bin/nginx-entrypoint.sh: no such file or directory` in a Docker container on Windows, follow these steps to resolve the issue. diff --git a/docs/07-troubleshooting/index.md b/docs/07-troubleshooting/index.md new file mode 100644 index 00000000..9662ac07 --- /dev/null +++ b/docs/07-troubleshooting/index.md @@ -0,0 +1,3 @@ +--- +title: Troubleshooting +--- diff --git a/docs/08-reference/01-build-version-10-images.md b/docs/08-reference/01-build-version-10-images.md index 613f06ee..5d3bba32 100644 --- a/docs/08-reference/01-build-version-10-images.md +++ b/docs/08-reference/01-build-version-10-images.md @@ -1,3 +1,7 @@ +--- +title: Build Version 10 +--- + Clone the version-10 branch of this repo ```shell diff --git a/docs/08-reference/index.md b/docs/08-reference/index.md new file mode 100644 index 00000000..1e6c5c77 --- /dev/null +++ b/docs/08-reference/index.md @@ -0,0 +1,3 @@ +--- +title: References +--- diff --git a/docs/getting-started.md b/docs/getting-started.md index e67f7415..72f9dee9 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -1,3 +1,7 @@ +--- +title: Getting Started +--- + # Getting Started with Frappe Docker _A comprehensive guide for developers getting started with Frappe Docker, with comparisons to Django for teams familiar with that framework_ diff --git a/docs/images/frappe_docker.png b/docs/images/frappe_docker.png new file mode 100644 index 0000000000000000000000000000000000000000..7f1138ab23a9ab37897d0ad4c4be60d64b03cfb9 GIT binary patch literal 45163 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 Vzu01V4C-=Zc+liP=Kixc{|ni=6.9.0'} + + '@babel/helper-validator-identifier@7.28.5': + resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.28.5': + resolution: {integrity: sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/types@7.28.5': + resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==} + engines: {node: '>=6.9.0'} + + '@docsearch/css@4.3.2': + resolution: {integrity: sha512-K3Yhay9MgkBjJJ0WEL5MxnACModX9xuNt3UlQQkDEDZJZ0+aeWKtOkxHNndMRkMBnHdYvQjxkm6mdlneOtU1IQ==} + + '@docsearch/js@4.3.2': + resolution: {integrity: sha512-xdfpPXMgKRY9EW7U1vtY7gLKbLZFa9ed+t0Dacquq8zXBqAlH9HlUf0h4Mhxm0xatsVeMaIR2wr/u6g0GsZyQw==} + + '@esbuild/aix-ppc64@0.25.12': + resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.25.12': + resolution: {integrity: sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.25.12': + resolution: {integrity: sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.25.12': + resolution: {integrity: sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.25.12': + resolution: {integrity: sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.25.12': + resolution: {integrity: sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.25.12': + resolution: {integrity: sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.25.12': + resolution: {integrity: sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.25.12': + resolution: {integrity: sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.25.12': + resolution: {integrity: sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.25.12': + resolution: {integrity: sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.25.12': + resolution: {integrity: sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.25.12': + resolution: {integrity: sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.25.12': + resolution: {integrity: sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.25.12': + resolution: {integrity: sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.25.12': + resolution: {integrity: sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.25.12': + resolution: {integrity: sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.25.12': + resolution: {integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.25.12': + resolution: {integrity: sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.25.12': + resolution: {integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.25.12': + resolution: {integrity: sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.25.12': + resolution: {integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.25.12': + resolution: {integrity: sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.25.12': + resolution: {integrity: sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.25.12': + resolution: {integrity: sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.25.12': + resolution: {integrity: sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@iconify-json/simple-icons@1.2.61': + resolution: {integrity: sha512-DG6z3VEAxtDEw/SuZssZ/E8EvhjBhFQqxpEo3uckRKiia3LfZHmM4cx4RsaO2qX1Bqo9uadR5c/hYavvUQVuHw==} + + '@iconify/types@2.0.0': + resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} + + '@isaacs/balanced-match@4.0.1': + resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} + engines: {node: 20 || >=22} + + '@isaacs/brace-expansion@5.0.0': + resolution: {integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==} + engines: {node: 20 || >=22} + + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@rolldown/pluginutils@1.0.0-beta.50': + resolution: {integrity: sha512-5e76wQiQVeL1ICOZVUg4LSOVYg9jyhGCin+icYozhsUzM+fHE7kddi1bdiE0jwVqTfkjba3jUFbEkoC9WkdvyA==} + + '@rollup/rollup-android-arm-eabi@4.53.3': + resolution: {integrity: sha512-mRSi+4cBjrRLoaal2PnqH82Wqyb+d3HsPUN/W+WslCXsZsyHa9ZeQQX/pQsZaVIWDkPcpV6jJ+3KLbTbgnwv8w==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.53.3': + resolution: {integrity: sha512-CbDGaMpdE9sh7sCmTrTUyllhrg65t6SwhjlMJsLr+J8YjFuPmCEjbBSx4Z/e4SmDyH3aB5hGaJUP2ltV/vcs4w==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.53.3': + resolution: {integrity: sha512-Nr7SlQeqIBpOV6BHHGZgYBuSdanCXuw09hon14MGOLGmXAFYjx1wNvquVPmpZnl0tLjg25dEdr4IQ6GgyToCUA==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.53.3': + resolution: {integrity: sha512-DZ8N4CSNfl965CmPktJ8oBnfYr3F8dTTNBQkRlffnUarJ2ohudQD17sZBa097J8xhQ26AwhHJ5mvUyQW8ddTsQ==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.53.3': + resolution: {integrity: sha512-yMTrCrK92aGyi7GuDNtGn2sNW+Gdb4vErx4t3Gv/Tr+1zRb8ax4z8GWVRfr3Jw8zJWvpGHNpss3vVlbF58DZ4w==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.53.3': + resolution: {integrity: sha512-lMfF8X7QhdQzseM6XaX0vbno2m3hlyZFhwcndRMw8fbAGUGL3WFMBdK0hbUBIUYcEcMhVLr1SIamDeuLBnXS+Q==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.53.3': + resolution: {integrity: sha512-k9oD15soC/Ln6d2Wv/JOFPzZXIAIFLp6B+i14KhxAfnq76ajt0EhYc5YPeX6W1xJkAdItcVT+JhKl1QZh44/qw==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.53.3': + resolution: {integrity: sha512-vTNlKq+N6CK/8UktsrFuc+/7NlEYVxgaEgRXVUVK258Z5ymho29skzW1sutgYjqNnquGwVUObAaxae8rZ6YMhg==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.53.3': + resolution: {integrity: sha512-RGrFLWgMhSxRs/EWJMIFM1O5Mzuz3Xy3/mnxJp/5cVhZ2XoCAxJnmNsEyeMJtpK+wu0FJFWz+QF4mjCA7AUQ3w==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.53.3': + resolution: {integrity: sha512-kASyvfBEWYPEwe0Qv4nfu6pNkITLTb32p4yTgzFCocHnJLAHs+9LjUu9ONIhvfT/5lv4YS5muBHyuV84epBo/A==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-loong64-gnu@4.53.3': + resolution: {integrity: sha512-JiuKcp2teLJwQ7vkJ95EwESWkNRFJD7TQgYmCnrPtlu50b4XvT5MOmurWNrCj3IFdyjBQ5p9vnrX4JM6I8OE7g==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-ppc64-gnu@4.53.3': + resolution: {integrity: sha512-EoGSa8nd6d3T7zLuqdojxC20oBfNT8nexBbB/rkxgKj5T5vhpAQKKnD+h3UkoMuTyXkP5jTjK/ccNRmQrPNDuw==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.53.3': + resolution: {integrity: sha512-4s+Wped2IHXHPnAEbIB0YWBv7SDohqxobiiPA1FIWZpX+w9o2i4LezzH/NkFUl8LRci/8udci6cLq+jJQlh+0g==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-riscv64-musl@4.53.3': + resolution: {integrity: sha512-68k2g7+0vs2u9CxDt5ktXTngsxOQkSEV/xBbwlqYcUrAVh6P9EgMZvFsnHy4SEiUl46Xf0IObWVbMvPrr2gw8A==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.53.3': + resolution: {integrity: sha512-VYsFMpULAz87ZW6BVYw3I6sWesGpsP9OPcyKe8ofdg9LHxSbRMd7zrVrr5xi/3kMZtpWL/wC+UIJWJYVX5uTKg==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.53.3': + resolution: {integrity: sha512-3EhFi1FU6YL8HTUJZ51imGJWEX//ajQPfqWLI3BQq4TlvHy4X0MOr5q3D2Zof/ka0d5FNdPwZXm3Yyib/UEd+w==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.53.3': + resolution: {integrity: sha512-eoROhjcc6HbZCJr+tvVT8X4fW3/5g/WkGvvmwz/88sDtSJzO7r/blvoBDgISDiCjDRZmHpwud7h+6Q9JxFwq1Q==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-openharmony-arm64@4.53.3': + resolution: {integrity: sha512-OueLAWgrNSPGAdUdIjSWXw+u/02BRTcnfw9PN41D2vq/JSEPnJnVuBgw18VkN8wcd4fjUs+jFHVM4t9+kBSNLw==} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.53.3': + resolution: {integrity: sha512-GOFuKpsxR/whszbF/bzydebLiXIHSgsEUp6M0JI8dWvi+fFa1TD6YQa4aSZHtpmh2/uAlj/Dy+nmby3TJ3pkTw==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.53.3': + resolution: {integrity: sha512-iah+THLcBJdpfZ1TstDFbKNznlzoxa8fmnFYK4V67HvmuNYkVdAywJSoteUszvBQ9/HqN2+9AZghbajMsFT+oA==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-gnu@4.53.3': + resolution: {integrity: sha512-J9QDiOIZlZLdcot5NXEepDkstocktoVjkaKUtqzgzpt2yWjGlbYiKyp05rWwk4nypbYUNoFAztEgixoLaSETkg==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.53.3': + resolution: {integrity: sha512-UhTd8u31dXadv0MopwGgNOBpUVROFKWVQgAg5N1ESyCz8AuBcMqm4AuTjrwgQKGDfoFuz02EuMRHQIw/frmYKQ==} + cpu: [x64] + os: [win32] + + '@shikijs/core@3.19.0': + resolution: {integrity: sha512-L7SrRibU7ZoYi1/TrZsJOFAnnHyLTE1SwHG1yNWjZIVCqjOEmCSuK2ZO9thnRbJG6TOkPp+Z963JmpCNw5nzvA==} + + '@shikijs/engine-javascript@3.19.0': + resolution: {integrity: sha512-ZfWJNm2VMhKkQIKT9qXbs76RRcT0SF/CAvEz0+RkpUDAoDaCx0uFdCGzSRiD9gSlhm6AHkjdieOBJMaO2eC1rQ==} + + '@shikijs/engine-oniguruma@3.19.0': + resolution: {integrity: sha512-1hRxtYIJfJSZeM5ivbUXv9hcJP3PWRo5prG/V2sWwiubUKTa+7P62d2qxCW8jiVFX4pgRHhnHNp+qeR7Xl+6kg==} + + '@shikijs/langs@3.19.0': + resolution: {integrity: sha512-dBMFzzg1QiXqCVQ5ONc0z2ebyoi5BKz+MtfByLm0o5/nbUu3Iz8uaTCa5uzGiscQKm7lVShfZHU1+OG3t5hgwg==} + + '@shikijs/themes@3.19.0': + resolution: {integrity: sha512-H36qw+oh91Y0s6OlFfdSuQ0Ld+5CgB/VE6gNPK+Hk4VRbVG/XQgkjnt4KzfnnoO6tZPtKJKHPjwebOCfjd6F8A==} + + '@shikijs/transformers@3.19.0': + resolution: {integrity: sha512-e6vwrsyw+wx4OkcrDbL+FVCxwx8jgKiCoXzakVur++mIWVcgpzIi8vxf4/b4dVTYrV/nUx5RjinMf4tq8YV8Fw==} + + '@shikijs/types@3.19.0': + resolution: {integrity: sha512-Z2hdeEQlzuntf/BZpFG8a+Fsw9UVXdML7w0o3TgSXV3yNESGon+bs9ITkQb3Ki7zxoXOOu5oJWqZ2uto06V9iQ==} + + '@shikijs/vscode-textmate@10.0.2': + resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} + + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + + '@types/hast@3.0.4': + resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} + + '@types/linkify-it@5.0.0': + resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==} + + '@types/markdown-it@14.1.2': + resolution: {integrity: sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==} + + '@types/mdast@4.0.4': + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} + + '@types/mdurl@2.0.0': + resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==} + + '@types/unist@3.0.3': + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + + '@types/web-bluetooth@0.0.21': + resolution: {integrity: sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==} + + '@ungap/structured-clone@1.3.0': + resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} + + '@vitejs/plugin-vue@6.0.2': + resolution: {integrity: sha512-iHmwV3QcVGGvSC1BG5bZ4z6iwa1SOpAPWmnjOErd4Ske+lZua5K9TtAVdx0gMBClJ28DViCbSmZitjWZsWO3LA==} + engines: {node: ^20.19.0 || >=22.12.0} + peerDependencies: + vite: ^5.0.0 || ^6.0.0 || ^7.0.0 + vue: ^3.2.25 + + '@vue/compiler-core@3.5.25': + resolution: {integrity: sha512-vay5/oQJdsNHmliWoZfHPoVZZRmnSWhug0BYT34njkYTPqClh3DNWLkZNJBVSjsNMrg0CCrBfoKkjZQPM/QVUw==} + + '@vue/compiler-dom@3.5.25': + resolution: {integrity: sha512-4We0OAcMZsKgYoGlMjzYvaoErltdFI2/25wqanuTu+S4gismOTRTBPi4IASOjxWdzIwrYSjnqONfKvuqkXzE2Q==} + + '@vue/compiler-sfc@3.5.25': + resolution: {integrity: sha512-PUgKp2rn8fFsI++lF2sO7gwO2d9Yj57Utr5yEsDf3GNaQcowCLKL7sf+LvVFvtJDXUp/03+dC6f2+LCv5aK1ag==} + + '@vue/compiler-ssr@3.5.25': + resolution: {integrity: sha512-ritPSKLBcParnsKYi+GNtbdbrIE1mtuFEJ4U1sWeuOMlIziK5GtOL85t5RhsNy4uWIXPgk+OUdpnXiTdzn8o3A==} + + '@vue/devtools-api@8.0.5': + resolution: {integrity: sha512-DgVcW8H/Nral7LgZEecYFFYXnAvGuN9C3L3DtWekAncFBedBczpNW8iHKExfaM559Zm8wQWrwtYZ9lXthEHtDw==} + + '@vue/devtools-kit@8.0.5': + resolution: {integrity: sha512-q2VV6x1U3KJMTQPUlRMyWEKVbcHuxhqJdSr6Jtjz5uAThAIrfJ6WVZdGZm5cuO63ZnSUz0RCsVwiUUb0mDV0Yg==} + + '@vue/devtools-shared@8.0.5': + resolution: {integrity: sha512-bRLn6/spxpmgLk+iwOrR29KrYnJjG9DGpHGkDFG82UM21ZpJ39ztUT9OXX3g+usW7/b2z+h46I9ZiYyB07XMXg==} + + '@vue/reactivity@3.5.25': + resolution: {integrity: sha512-5xfAypCQepv4Jog1U4zn8cZIcbKKFka3AgWHEFQeK65OW+Ys4XybP6z2kKgws4YB43KGpqp5D/K3go2UPPunLA==} + + '@vue/runtime-core@3.5.25': + resolution: {integrity: sha512-Z751v203YWwYzy460bzsYQISDfPjHTl+6Zzwo/a3CsAf+0ccEjQ8c+0CdX1WsumRTHeywvyUFtW6KvNukT/smA==} + + '@vue/runtime-dom@3.5.25': + resolution: {integrity: sha512-a4WrkYFbb19i9pjkz38zJBg8wa/rboNERq3+hRRb0dHiJh13c+6kAbgqCPfMaJ2gg4weWD3APZswASOfmKwamA==} + + '@vue/server-renderer@3.5.25': + resolution: {integrity: sha512-UJaXR54vMG61i8XNIzTSf2Q7MOqZHpp8+x3XLGtE3+fL+nQd+k7O5+X3D/uWrnQXOdMw5VPih+Uremcw+u1woQ==} + peerDependencies: + vue: 3.5.25 + + '@vue/shared@3.5.25': + resolution: {integrity: sha512-AbOPdQQnAnzs58H2FrrDxYj/TJfmeS2jdfEEhgiKINy+bnOANmVizIEgq1r+C5zsbs6l1CCQxtcj71rwNQ4jWg==} + + '@vueuse/core@14.1.0': + resolution: {integrity: sha512-rgBinKs07hAYyPF834mDTigH7BtPqvZ3Pryuzt1SD/lg5wEcWqvwzXXYGEDb2/cP0Sj5zSvHl3WkmMELr5kfWw==} + peerDependencies: + vue: ^3.5.0 + + '@vueuse/integrations@14.1.0': + resolution: {integrity: sha512-eNQPdisnO9SvdydTIXnTE7c29yOsJBD/xkwEyQLdhDC/LKbqrFpXHb3uS//7NcIrQO3fWVuvMGp8dbK6mNEMCA==} + peerDependencies: + async-validator: ^4 + axios: ^1 + change-case: ^5 + drauu: ^0.4 + focus-trap: ^7 + fuse.js: ^7 + idb-keyval: ^6 + jwt-decode: ^4 + nprogress: ^0.2 + qrcode: ^1.5 + sortablejs: ^1 + universal-cookie: ^7 || ^8 + vue: ^3.5.0 + peerDependenciesMeta: + async-validator: + optional: true + axios: + optional: true + change-case: + optional: true + drauu: + optional: true + focus-trap: + optional: true + fuse.js: + optional: true + idb-keyval: + optional: true + jwt-decode: + optional: true + nprogress: + optional: true + qrcode: + optional: true + sortablejs: + optional: true + universal-cookie: + optional: true + + '@vueuse/metadata@14.1.0': + resolution: {integrity: sha512-7hK4g015rWn2PhKcZ99NyT+ZD9sbwm7SGvp7k+k+rKGWnLjS/oQozoIZzWfCewSUeBmnJkIb+CNr7Zc/EyRnnA==} + + '@vueuse/shared@14.1.0': + resolution: {integrity: sha512-EcKxtYvn6gx1F8z9J5/rsg3+lTQnvOruQd8fUecW99DCK04BkWD7z5KQ/wTAx+DazyoEE9dJt/zV8OIEQbM6kw==} + peerDependencies: + vue: ^3.5.0 + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.2.2: + resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} + engines: {node: '>=12'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@6.2.3: + resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} + engines: {node: '>=12'} + + argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + + birpc@2.9.0: + resolution: {integrity: sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw==} + + ccount@2.0.1: + resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + + character-entities-html4@2.1.0: + resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} + + character-entities-legacy@3.0.0: + resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + comma-separated-tokens@2.0.3: + resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + + copy-anything@4.0.5: + resolution: {integrity: sha512-7Vv6asjS4gMOuILabD3l739tsaxFQmC+a7pLZm02zyvs8p977bL3zEgq3yDk5rn9B0PbYgIv++jmHcuUab4RhA==} + engines: {node: '>=18'} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + + devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + esbuild@0.25.12: + resolution: {integrity: sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==} + engines: {node: '>=18'} + hasBin: true + + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + + extend-shallow@2.0.1: + resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} + engines: {node: '>=0.10.0'} + + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + focus-trap@7.6.6: + resolution: {integrity: sha512-v/Z8bvMCajtx4mEXmOo7QEsIzlIOqRXTIwgUfsFOF9gEsespdbD0AkPIka1bSXZ8Y8oZ+2IVDQZePkTfEHZl7Q==} + + foreground-child@3.3.1: + resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} + engines: {node: '>=14'} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + glob@11.1.0: + resolution: {integrity: sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==} + engines: {node: 20 || >=22} + hasBin: true + + gray-matter@4.0.3: + resolution: {integrity: sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==} + engines: {node: '>=6.0'} + + hast-util-to-html@9.0.5: + resolution: {integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==} + + hast-util-whitespace@3.0.0: + resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} + + hookable@5.5.3: + resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==} + + htm@3.1.1: + resolution: {integrity: sha512-983Vyg8NwUE7JkZ6NmOqpCZ+sh1bKv2iYTlUkzlWmA5JD2acKoxd4KVxbMmxX/85mtfdnDmTFoNKcg5DGAvxNQ==} + + html-void-elements@3.0.0: + resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} + + is-extendable@0.1.1: + resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-what@5.5.0: + resolution: {integrity: sha512-oG7cgbmg5kLYae2N5IVd3jm2s+vldjxJzK1pcu9LfpGuQ93MQSzo0okvRna+7y5ifrD+20FE8FvjusyGaz14fw==} + engines: {node: '>=18'} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + jackspeak@4.1.1: + resolution: {integrity: sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==} + engines: {node: 20 || >=22} + + js-yaml@3.14.2: + resolution: {integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==} + hasBin: true + + kind-of@6.0.3: + resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} + engines: {node: '>=0.10.0'} + + lru-cache@11.2.4: + resolution: {integrity: sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==} + engines: {node: 20 || >=22} + + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + + mark.js@8.11.1: + resolution: {integrity: sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==} + + mdast-util-to-hast@13.2.1: + resolution: {integrity: sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==} + + micromark-util-character@2.1.1: + resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} + + micromark-util-encode@2.0.1: + resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} + + micromark-util-sanitize-uri@2.0.1: + resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} + + micromark-util-symbol@2.0.1: + resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} + + micromark-util-types@2.0.2: + resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} + + minimatch@10.1.1: + resolution: {integrity: sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==} + engines: {node: 20 || >=22} + + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + + minisearch@7.2.0: + resolution: {integrity: sha512-dqT2XBYUOZOiC5t2HRnwADjhNS2cecp9u+TJRiJ1Qp/f5qjkeT5APcGPjHw+bz89Ms8Jp+cG4AlE+QZ/QnDglg==} + + mitt@3.0.1: + resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + oniguruma-parser@0.12.1: + resolution: {integrity: sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w==} + + oniguruma-to-es@4.3.4: + resolution: {integrity: sha512-3VhUGN3w2eYxnTzHn+ikMI+fp/96KoRSVK9/kMTcFqj1NRDh2IhQCKvYxDnWePKRXY/AqH+Fuiyb7VHSzBjHfA==} + + package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-scurry@2.0.1: + resolution: {integrity: sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==} + engines: {node: 20 || >=22} + + perfect-debounce@2.0.0: + resolution: {integrity: sha512-fkEH/OBiKrqqI/yIgjR92lMfs2K8105zt/VT6+7eTjNwisrsh47CeIED9z58zI7DfKdH3uHAn25ziRZn3kgAow==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@4.0.3: + resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} + engines: {node: '>=12'} + + postcss@8.5.6: + resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} + engines: {node: ^10 || ^12 || >=14} + + property-information@7.1.0: + resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==} + + qsu@1.10.4: + resolution: {integrity: sha512-v5RhwvHMkDdbXEaAxQh5re8q7DiG6EE70+CNwYVA6wZsa4gUrpur+D8lIO3PrzeCj3azc/S79X5v3BH8ILfr9A==} + engines: {node: '>=18.0.0'} + + regex-recursion@6.0.2: + resolution: {integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==} + + regex-utilities@2.3.0: + resolution: {integrity: sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==} + + regex@6.0.1: + resolution: {integrity: sha512-uorlqlzAKjKQZ5P+kTJr3eeJGSVroLKoHmquUj4zHWuR+hEyNqlXsSKlYYF5F4NI6nl7tWCs0apKJ0lmfsXAPA==} + + rfdc@1.4.1: + resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} + + rollup@4.53.3: + resolution: {integrity: sha512-w8GmOxZfBmKknvdXU1sdM9NHcoQejwF/4mNgj2JuEEdRaHwwF12K7e9eXn1nLZ07ad+du76mkVsyeb2rKGllsA==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + section-matter@1.0.0: + resolution: {integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==} + engines: {node: '>=4'} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + shiki@3.19.0: + resolution: {integrity: sha512-77VJr3OR/VUZzPiStyRhADmO2jApMM0V2b1qf0RpfWya8Zr1PeZev5AEpPGAAKWdiYUtcZGBE4F5QvJml1PvWA==} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + space-separated-tokens@2.0.2: + resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + + speakingurl@14.0.1: + resolution: {integrity: sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==} + engines: {node: '>=0.10.0'} + + sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + + stringify-entities@4.0.4: + resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.1.2: + resolution: {integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==} + engines: {node: '>=12'} + + strip-bom-string@1.0.0: + resolution: {integrity: sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==} + engines: {node: '>=0.10.0'} + + superjson@2.2.6: + resolution: {integrity: sha512-H+ue8Zo4vJmV2nRjpx86P35lzwDT3nItnIsocgumgr0hHMQ+ZGq5vrERg9kJBo5AWGmxZDhzDo+WVIJqkB0cGA==} + engines: {node: '>=16'} + + tabbable@6.3.0: + resolution: {integrity: sha512-EIHvdY5bPLuWForiR/AN2Bxngzpuwn1is4asboytXtpTgsArc+WmSJKVLlhdh71u7jFcryDqB2A8lQvj78MkyQ==} + + tinyglobby@0.2.15: + resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} + engines: {node: '>=12.0.0'} + + trim-lines@3.0.1: + resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} + + unist-util-is@6.0.1: + resolution: {integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==} + + unist-util-position@5.0.0: + resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} + + unist-util-stringify-position@4.0.0: + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + + unist-util-visit-parents@6.0.2: + resolution: {integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==} + + unist-util-visit@5.0.0: + resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==} + + vfile-message@4.0.3: + resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} + + vfile@6.0.3: + resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + + vite@7.2.6: + resolution: {integrity: sha512-tI2l/nFHC5rLh7+5+o7QjKjSR04ivXDF4jcgV0f/bTQ+OJiITy5S6gaynVsEM+7RqzufMnVbIon6Sr5x1SDYaQ==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + jiti: '>=1.21.0' + less: ^4.0.0 + lightningcss: ^1.21.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + vitepress-sidebar@1.33.1: + resolution: {integrity: sha512-wPUbXezGakVldawixeRW5tKQTLKoMj2t4nWoThKfCltBM/9a38IE+wCXmmRNW22ZKC32SD/X/sG6NyCTK8QBRg==} + engines: {node: '>=18.0.0'} + + vitepress@2.0.0-alpha.15: + resolution: {integrity: sha512-jhjSYd10Z6RZiKOa7jy0xMVf5NB5oSc/lS3bD/QoUc6V8PrvQR5JhC9104NEt6+oTGY/ftieVWxY9v7YI+1IjA==} + hasBin: true + peerDependencies: + markdown-it-mathjax3: ^4 + oxc-minify: '*' + postcss: ^8 + peerDependenciesMeta: + markdown-it-mathjax3: + optional: true + oxc-minify: + optional: true + postcss: + optional: true + + vue@3.5.25: + resolution: {integrity: sha512-YLVdgv2K13WJ6n+kD5owehKtEXwdwXuj2TTyJMsO7pSeKw2bfRNZGjhB7YzrpbMYj5b5QsUebHpOqR3R3ziy/g==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + + zwitch@2.0.4: + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + +snapshots: + + '@babel/helper-string-parser@7.27.1': {} + + '@babel/helper-validator-identifier@7.28.5': {} + + '@babel/parser@7.28.5': + dependencies: + '@babel/types': 7.28.5 + + '@babel/types@7.28.5': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + + '@docsearch/css@4.3.2': {} + + '@docsearch/js@4.3.2': + dependencies: + htm: 3.1.1 + + '@esbuild/aix-ppc64@0.25.12': + optional: true + + '@esbuild/android-arm64@0.25.12': + optional: true + + '@esbuild/android-arm@0.25.12': + optional: true + + '@esbuild/android-x64@0.25.12': + optional: true + + '@esbuild/darwin-arm64@0.25.12': + optional: true + + '@esbuild/darwin-x64@0.25.12': + optional: true + + '@esbuild/freebsd-arm64@0.25.12': + optional: true + + '@esbuild/freebsd-x64@0.25.12': + optional: true + + '@esbuild/linux-arm64@0.25.12': + optional: true + + '@esbuild/linux-arm@0.25.12': + optional: true + + '@esbuild/linux-ia32@0.25.12': + optional: true + + '@esbuild/linux-loong64@0.25.12': + optional: true + + '@esbuild/linux-mips64el@0.25.12': + optional: true + + '@esbuild/linux-ppc64@0.25.12': + optional: true + + '@esbuild/linux-riscv64@0.25.12': + optional: true + + '@esbuild/linux-s390x@0.25.12': + optional: true + + '@esbuild/linux-x64@0.25.12': + optional: true + + '@esbuild/netbsd-arm64@0.25.12': + optional: true + + '@esbuild/netbsd-x64@0.25.12': + optional: true + + '@esbuild/openbsd-arm64@0.25.12': + optional: true + + '@esbuild/openbsd-x64@0.25.12': + optional: true + + '@esbuild/openharmony-arm64@0.25.12': + optional: true + + '@esbuild/sunos-x64@0.25.12': + optional: true + + '@esbuild/win32-arm64@0.25.12': + optional: true + + '@esbuild/win32-ia32@0.25.12': + optional: true + + '@esbuild/win32-x64@0.25.12': + optional: true + + '@iconify-json/simple-icons@1.2.61': + dependencies: + '@iconify/types': 2.0.0 + + '@iconify/types@2.0.0': {} + + '@isaacs/balanced-match@4.0.1': {} + + '@isaacs/brace-expansion@5.0.0': + dependencies: + '@isaacs/balanced-match': 4.0.1 + + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.2 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@rolldown/pluginutils@1.0.0-beta.50': {} + + '@rollup/rollup-android-arm-eabi@4.53.3': + optional: true + + '@rollup/rollup-android-arm64@4.53.3': + optional: true + + '@rollup/rollup-darwin-arm64@4.53.3': + optional: true + + '@rollup/rollup-darwin-x64@4.53.3': + optional: true + + '@rollup/rollup-freebsd-arm64@4.53.3': + optional: true + + '@rollup/rollup-freebsd-x64@4.53.3': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.53.3': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.53.3': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.53.3': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.53.3': + optional: true + + '@rollup/rollup-linux-loong64-gnu@4.53.3': + optional: true + + '@rollup/rollup-linux-ppc64-gnu@4.53.3': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.53.3': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.53.3': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.53.3': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.53.3': + optional: true + + '@rollup/rollup-linux-x64-musl@4.53.3': + optional: true + + '@rollup/rollup-openharmony-arm64@4.53.3': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.53.3': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.53.3': + optional: true + + '@rollup/rollup-win32-x64-gnu@4.53.3': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.53.3': + optional: true + + '@shikijs/core@3.19.0': + dependencies: + '@shikijs/types': 3.19.0 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + hast-util-to-html: 9.0.5 + + '@shikijs/engine-javascript@3.19.0': + dependencies: + '@shikijs/types': 3.19.0 + '@shikijs/vscode-textmate': 10.0.2 + oniguruma-to-es: 4.3.4 + + '@shikijs/engine-oniguruma@3.19.0': + dependencies: + '@shikijs/types': 3.19.0 + '@shikijs/vscode-textmate': 10.0.2 + + '@shikijs/langs@3.19.0': + dependencies: + '@shikijs/types': 3.19.0 + + '@shikijs/themes@3.19.0': + dependencies: + '@shikijs/types': 3.19.0 + + '@shikijs/transformers@3.19.0': + dependencies: + '@shikijs/core': 3.19.0 + '@shikijs/types': 3.19.0 + + '@shikijs/types@3.19.0': + dependencies: + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + + '@shikijs/vscode-textmate@10.0.2': {} + + '@types/estree@1.0.8': {} + + '@types/hast@3.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/linkify-it@5.0.0': {} + + '@types/markdown-it@14.1.2': + dependencies: + '@types/linkify-it': 5.0.0 + '@types/mdurl': 2.0.0 + + '@types/mdast@4.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/mdurl@2.0.0': {} + + '@types/unist@3.0.3': {} + + '@types/web-bluetooth@0.0.21': {} + + '@ungap/structured-clone@1.3.0': {} + + '@vitejs/plugin-vue@6.0.2(vite@7.2.6)(vue@3.5.25)': + dependencies: + '@rolldown/pluginutils': 1.0.0-beta.50 + vite: 7.2.6 + vue: 3.5.25 + + '@vue/compiler-core@3.5.25': + dependencies: + '@babel/parser': 7.28.5 + '@vue/shared': 3.5.25 + entities: 4.5.0 + estree-walker: 2.0.2 + source-map-js: 1.2.1 + + '@vue/compiler-dom@3.5.25': + dependencies: + '@vue/compiler-core': 3.5.25 + '@vue/shared': 3.5.25 + + '@vue/compiler-sfc@3.5.25': + dependencies: + '@babel/parser': 7.28.5 + '@vue/compiler-core': 3.5.25 + '@vue/compiler-dom': 3.5.25 + '@vue/compiler-ssr': 3.5.25 + '@vue/shared': 3.5.25 + estree-walker: 2.0.2 + magic-string: 0.30.21 + postcss: 8.5.6 + source-map-js: 1.2.1 + + '@vue/compiler-ssr@3.5.25': + dependencies: + '@vue/compiler-dom': 3.5.25 + '@vue/shared': 3.5.25 + + '@vue/devtools-api@8.0.5': + dependencies: + '@vue/devtools-kit': 8.0.5 + + '@vue/devtools-kit@8.0.5': + dependencies: + '@vue/devtools-shared': 8.0.5 + birpc: 2.9.0 + hookable: 5.5.3 + mitt: 3.0.1 + perfect-debounce: 2.0.0 + speakingurl: 14.0.1 + superjson: 2.2.6 + + '@vue/devtools-shared@8.0.5': + dependencies: + rfdc: 1.4.1 + + '@vue/reactivity@3.5.25': + dependencies: + '@vue/shared': 3.5.25 + + '@vue/runtime-core@3.5.25': + dependencies: + '@vue/reactivity': 3.5.25 + '@vue/shared': 3.5.25 + + '@vue/runtime-dom@3.5.25': + dependencies: + '@vue/reactivity': 3.5.25 + '@vue/runtime-core': 3.5.25 + '@vue/shared': 3.5.25 + csstype: 3.2.3 + + '@vue/server-renderer@3.5.25(vue@3.5.25)': + dependencies: + '@vue/compiler-ssr': 3.5.25 + '@vue/shared': 3.5.25 + vue: 3.5.25 + + '@vue/shared@3.5.25': {} + + '@vueuse/core@14.1.0(vue@3.5.25)': + dependencies: + '@types/web-bluetooth': 0.0.21 + '@vueuse/metadata': 14.1.0 + '@vueuse/shared': 14.1.0(vue@3.5.25) + vue: 3.5.25 + + '@vueuse/integrations@14.1.0(focus-trap@7.6.6)(vue@3.5.25)': + dependencies: + '@vueuse/core': 14.1.0(vue@3.5.25) + '@vueuse/shared': 14.1.0(vue@3.5.25) + vue: 3.5.25 + optionalDependencies: + focus-trap: 7.6.6 + + '@vueuse/metadata@14.1.0': {} + + '@vueuse/shared@14.1.0(vue@3.5.25)': + dependencies: + vue: 3.5.25 + + ansi-regex@5.0.1: {} + + ansi-regex@6.2.2: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@6.2.3: {} + + argparse@1.0.10: + dependencies: + sprintf-js: 1.0.3 + + birpc@2.9.0: {} + + ccount@2.0.1: {} + + character-entities-html4@2.1.0: {} + + character-entities-legacy@3.0.0: {} + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + comma-separated-tokens@2.0.3: {} + + copy-anything@4.0.5: + dependencies: + is-what: 5.5.0 + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + csstype@3.2.3: {} + + dequal@2.0.3: {} + + devlop@1.1.0: + dependencies: + dequal: 2.0.3 + + eastasianwidth@0.2.0: {} + + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + + entities@4.5.0: {} + + esbuild@0.25.12: + optionalDependencies: + '@esbuild/aix-ppc64': 0.25.12 + '@esbuild/android-arm': 0.25.12 + '@esbuild/android-arm64': 0.25.12 + '@esbuild/android-x64': 0.25.12 + '@esbuild/darwin-arm64': 0.25.12 + '@esbuild/darwin-x64': 0.25.12 + '@esbuild/freebsd-arm64': 0.25.12 + '@esbuild/freebsd-x64': 0.25.12 + '@esbuild/linux-arm': 0.25.12 + '@esbuild/linux-arm64': 0.25.12 + '@esbuild/linux-ia32': 0.25.12 + '@esbuild/linux-loong64': 0.25.12 + '@esbuild/linux-mips64el': 0.25.12 + '@esbuild/linux-ppc64': 0.25.12 + '@esbuild/linux-riscv64': 0.25.12 + '@esbuild/linux-s390x': 0.25.12 + '@esbuild/linux-x64': 0.25.12 + '@esbuild/netbsd-arm64': 0.25.12 + '@esbuild/netbsd-x64': 0.25.12 + '@esbuild/openbsd-arm64': 0.25.12 + '@esbuild/openbsd-x64': 0.25.12 + '@esbuild/openharmony-arm64': 0.25.12 + '@esbuild/sunos-x64': 0.25.12 + '@esbuild/win32-arm64': 0.25.12 + '@esbuild/win32-ia32': 0.25.12 + '@esbuild/win32-x64': 0.25.12 + + esprima@4.0.1: {} + + estree-walker@2.0.2: {} + + extend-shallow@2.0.1: + dependencies: + is-extendable: 0.1.1 + + fdir@6.5.0(picomatch@4.0.3): + optionalDependencies: + picomatch: 4.0.3 + + focus-trap@7.6.6: + dependencies: + tabbable: 6.3.0 + + foreground-child@3.3.1: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + + fsevents@2.3.3: + optional: true + + glob@11.1.0: + dependencies: + foreground-child: 3.3.1 + jackspeak: 4.1.1 + minimatch: 10.1.1 + minipass: 7.1.2 + package-json-from-dist: 1.0.1 + path-scurry: 2.0.1 + + gray-matter@4.0.3: + dependencies: + js-yaml: 3.14.2 + kind-of: 6.0.3 + section-matter: 1.0.0 + strip-bom-string: 1.0.0 + + hast-util-to-html@9.0.5: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + comma-separated-tokens: 2.0.3 + hast-util-whitespace: 3.0.0 + html-void-elements: 3.0.0 + mdast-util-to-hast: 13.2.1 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + stringify-entities: 4.0.4 + zwitch: 2.0.4 + + hast-util-whitespace@3.0.0: + dependencies: + '@types/hast': 3.0.4 + + hookable@5.5.3: {} + + htm@3.1.1: {} + + html-void-elements@3.0.0: {} + + is-extendable@0.1.1: {} + + is-fullwidth-code-point@3.0.0: {} + + is-what@5.5.0: {} + + isexe@2.0.0: {} + + jackspeak@4.1.1: + dependencies: + '@isaacs/cliui': 8.0.2 + + js-yaml@3.14.2: + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + + kind-of@6.0.3: {} + + lru-cache@11.2.4: {} + + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + mark.js@8.11.1: {} + + mdast-util-to-hast@13.2.1: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@ungap/structured-clone': 1.3.0 + devlop: 1.1.0 + micromark-util-sanitize-uri: 2.0.1 + trim-lines: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit: 5.0.0 + vfile: 6.0.3 + + micromark-util-character@2.1.1: + dependencies: + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-encode@2.0.1: {} + + micromark-util-sanitize-uri@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-encode: 2.0.1 + micromark-util-symbol: 2.0.1 + + micromark-util-symbol@2.0.1: {} + + micromark-util-types@2.0.2: {} + + minimatch@10.1.1: + dependencies: + '@isaacs/brace-expansion': 5.0.0 + + minipass@7.1.2: {} + + minisearch@7.2.0: {} + + mitt@3.0.1: {} + + nanoid@3.3.11: {} + + oniguruma-parser@0.12.1: {} + + oniguruma-to-es@4.3.4: + dependencies: + oniguruma-parser: 0.12.1 + regex: 6.0.1 + regex-recursion: 6.0.2 + + package-json-from-dist@1.0.1: {} + + path-key@3.1.1: {} + + path-scurry@2.0.1: + dependencies: + lru-cache: 11.2.4 + minipass: 7.1.2 + + perfect-debounce@2.0.0: {} + + picocolors@1.1.1: {} + + picomatch@4.0.3: {} + + postcss@8.5.6: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + property-information@7.1.0: {} + + qsu@1.10.4: {} + + regex-recursion@6.0.2: + dependencies: + regex-utilities: 2.3.0 + + regex-utilities@2.3.0: {} + + regex@6.0.1: + dependencies: + regex-utilities: 2.3.0 + + rfdc@1.4.1: {} + + rollup@4.53.3: + dependencies: + '@types/estree': 1.0.8 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.53.3 + '@rollup/rollup-android-arm64': 4.53.3 + '@rollup/rollup-darwin-arm64': 4.53.3 + '@rollup/rollup-darwin-x64': 4.53.3 + '@rollup/rollup-freebsd-arm64': 4.53.3 + '@rollup/rollup-freebsd-x64': 4.53.3 + '@rollup/rollup-linux-arm-gnueabihf': 4.53.3 + '@rollup/rollup-linux-arm-musleabihf': 4.53.3 + '@rollup/rollup-linux-arm64-gnu': 4.53.3 + '@rollup/rollup-linux-arm64-musl': 4.53.3 + '@rollup/rollup-linux-loong64-gnu': 4.53.3 + '@rollup/rollup-linux-ppc64-gnu': 4.53.3 + '@rollup/rollup-linux-riscv64-gnu': 4.53.3 + '@rollup/rollup-linux-riscv64-musl': 4.53.3 + '@rollup/rollup-linux-s390x-gnu': 4.53.3 + '@rollup/rollup-linux-x64-gnu': 4.53.3 + '@rollup/rollup-linux-x64-musl': 4.53.3 + '@rollup/rollup-openharmony-arm64': 4.53.3 + '@rollup/rollup-win32-arm64-msvc': 4.53.3 + '@rollup/rollup-win32-ia32-msvc': 4.53.3 + '@rollup/rollup-win32-x64-gnu': 4.53.3 + '@rollup/rollup-win32-x64-msvc': 4.53.3 + fsevents: 2.3.3 + + section-matter@1.0.0: + dependencies: + extend-shallow: 2.0.1 + kind-of: 6.0.3 + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + shiki@3.19.0: + dependencies: + '@shikijs/core': 3.19.0 + '@shikijs/engine-javascript': 3.19.0 + '@shikijs/engine-oniguruma': 3.19.0 + '@shikijs/langs': 3.19.0 + '@shikijs/themes': 3.19.0 + '@shikijs/types': 3.19.0 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + + signal-exit@4.1.0: {} + + source-map-js@1.2.1: {} + + space-separated-tokens@2.0.2: {} + + speakingurl@14.0.1: {} + + sprintf-js@1.0.3: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.2 + + stringify-entities@4.0.4: + dependencies: + character-entities-html4: 2.1.0 + character-entities-legacy: 3.0.0 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.1.2: + dependencies: + ansi-regex: 6.2.2 + + strip-bom-string@1.0.0: {} + + superjson@2.2.6: + dependencies: + copy-anything: 4.0.5 + + tabbable@6.3.0: {} + + tinyglobby@0.2.15: + dependencies: + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + + trim-lines@3.0.1: {} + + unist-util-is@6.0.1: + dependencies: + '@types/unist': 3.0.3 + + unist-util-position@5.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-stringify-position@4.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-visit-parents@6.0.2: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + + unist-util-visit@5.0.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 + + vfile-message@4.0.3: + dependencies: + '@types/unist': 3.0.3 + unist-util-stringify-position: 4.0.0 + + vfile@6.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile-message: 4.0.3 + + vite@7.2.6: + dependencies: + esbuild: 0.25.12 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + postcss: 8.5.6 + rollup: 4.53.3 + tinyglobby: 0.2.15 + optionalDependencies: + fsevents: 2.3.3 + + vitepress-sidebar@1.33.1: + dependencies: + glob: 11.1.0 + gray-matter: 4.0.3 + qsu: 1.10.4 + + vitepress@2.0.0-alpha.15(postcss@8.5.6): + dependencies: + '@docsearch/css': 4.3.2 + '@docsearch/js': 4.3.2 + '@iconify-json/simple-icons': 1.2.61 + '@shikijs/core': 3.19.0 + '@shikijs/transformers': 3.19.0 + '@shikijs/types': 3.19.0 + '@types/markdown-it': 14.1.2 + '@vitejs/plugin-vue': 6.0.2(vite@7.2.6)(vue@3.5.25) + '@vue/devtools-api': 8.0.5 + '@vue/shared': 3.5.25 + '@vueuse/core': 14.1.0(vue@3.5.25) + '@vueuse/integrations': 14.1.0(focus-trap@7.6.6)(vue@3.5.25) + focus-trap: 7.6.6 + mark.js: 8.11.1 + minisearch: 7.2.0 + shiki: 3.19.0 + vite: 7.2.6 + vue: 3.5.25 + optionalDependencies: + postcss: 8.5.6 + transitivePeerDependencies: + - '@types/node' + - async-validator + - axios + - change-case + - drauu + - fuse.js + - idb-keyval + - jiti + - jwt-decode + - less + - lightningcss + - nprogress + - qrcode + - sass + - sass-embedded + - sortablejs + - stylus + - sugarss + - terser + - tsx + - typescript + - universal-cookie + - yaml + + vue@3.5.25: + dependencies: + '@vue/compiler-dom': 3.5.25 + '@vue/compiler-sfc': 3.5.25 + '@vue/runtime-dom': 3.5.25 + '@vue/server-renderer': 3.5.25(vue@3.5.25) + '@vue/shared': 3.5.25 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.3 + string-width: 5.1.2 + strip-ansi: 7.1.2 + + zwitch@2.0.4: {} From a48633d33c6bfa29bcac5939cad5116a8f191869 Mon Sep 17 00:00:00 2001 From: adithya Date: Sat, 6 Dec 2025 00:11:26 +0530 Subject: [PATCH 150/279] feat: Deploy to GitHub pages fix: pnpm Actions fix, corrected base fix: Build error fixes fix: Images not showing up in pages fix: Moved logo to public path --- .github/workflows/publish_docs.yml | 55 ++++++++++++++++++ docs/.vitepress/config.mts | 3 +- docs/getting-started.md | 16 ++--- docs/index.md | 2 +- .../frappe-docker.png} | Bin 5 files changed, 66 insertions(+), 10 deletions(-) create mode 100644 .github/workflows/publish_docs.yml rename docs/{images/frappe_docker.png => public/frappe-docker.png} (100%) diff --git a/.github/workflows/publish_docs.yml b/.github/workflows/publish_docs.yml new file mode 100644 index 00000000..f8cd75f5 --- /dev/null +++ b/.github/workflows/publish_docs.yml @@ -0,0 +1,55 @@ +name: Deploy Frappe Docker Docs to GitHub Pages + +on: + push: + branches: [docs] + paths: + - "docs/**" + - ".github/workflows/publish_docs.yml" + workflow_dispatch: + +permissions: + contents: read + pages: write + id-token: write + +concurrency: + group: pages + cancel-in-progress: true + +jobs: + build-and-deploy: + runs-on: ubuntu-latest + strategy: + matrix: + node-version: [20] + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install pnpm + uses: pnpm/action-setup@v4 + with: + version: 10 + + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + cache: "pnpm" + + - name: Install dependencies + run: pnpm i --frozen-lockfile + + - name: Build Docs site + run: pnpm docs:build + + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + path: docs/.vitepress/dist + + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts index 316d9829..495139ae 100644 --- a/docs/.vitepress/config.mts +++ b/docs/.vitepress/config.mts @@ -5,8 +5,9 @@ import { withSidebar } from "vitepress-sidebar"; const vitePressOptions = { title: "Frappe Docker Docs", description: "Frappe in a Container", + base: "/frappe_docker/", themeConfig: { - logo: "../images/frappe_docker.png", + logo: "/frappe-docker.png", // https://vitepress.dev/reference/default-theme-config nav: [{ text: "Home", link: "/" }], diff --git a/docs/getting-started.md b/docs/getting-started.md index 72f9dee9..585b1f3f 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -89,7 +89,7 @@ Four predefined Dockerfiles are available, each serving different use cases: - **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 [docs/container-setup/01-overview.md](container-setup/01-overview.md). +> **Note:** For detailed build arguments and advanced configuration options, see [docs/02-setup/01-overview.md](02-setup/01-overview.md). ### πŸ“ overrides/ - Compose File Extensions @@ -859,11 +859,11 @@ Many teams use both: Frappe for back-office/admin tools, Django for customer-fac ### Key Files in This Repository -- [`docs/development.md`](development.md) - Detailed development setup -- [`docs/container-setup/env-variables.md`](container-setup/env-variables.md) - Environment variable reference -- [`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 +- [`docs/05-development/01-development.md`](05-development/01-development.md) - Detailed development setup +- [`docs/02-setup/04-env-variables.md`](02-setup/04-env-variables.md) - Environment variable reference +- [`docs/02-setup/07-single-server-example.md`](02-setup/07-single-server-example.md) - Production deployment guide +- [`docs/04-operations/01-site-operations.md`](04-operations/01-site-operations.md) - Common site management tasks +- `development/installer.py` - Automated setup script - [`pwd.yml`](../pwd.yml) - Quick test configuration - [`compose.yaml`](../compose.yaml) - Base Docker Compose configuration @@ -958,7 +958,7 @@ bench update # Update framework and apps ### Getting Help -1. **Check existing docs** - Most issues covered in [`docs/troubleshoot.md`](troubleshoot.md) +1. **Check existing docs** - Most issues covered in [`docs/07-troubleshooting/01-troubleshoot.md](07-troubleshooting/01-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) @@ -969,7 +969,7 @@ Found issues or improvements for this guide? - Create an issue: [frappe_docker/issues](https://github.com/frappe/frappe_docker/issues) - Submit focused PRs: keep updates scoped and split large efforts across multiple pull requests. -- Review [CONTRIBUTING.md](../CONTRIBUTING.md) for coding standards and review expectations. +- Review CONTRIBUTING.md: for coding standards and review expectations. --- diff --git a/docs/index.md b/docs/index.md index 9c2f9096..3a108011 100644 --- a/docs/index.md +++ b/docs/index.md @@ -7,7 +7,7 @@ hero: # text: "Frappe in Container" tagline: "Documentation to use Docker based setup of Frappe framework" image: - src: ./images/frappe_docker.png + src: /frappe-docker.png actions: - theme: brand text: Getting Started diff --git a/docs/images/frappe_docker.png b/docs/public/frappe-docker.png similarity index 100% rename from docs/images/frappe_docker.png rename to docs/public/frappe-docker.png From c81d6c794bdc916d10a7720afdb98eeae47f6d40 Mon Sep 17 00:00:00 2001 From: adithya Date: Fri, 6 Feb 2026 23:21:39 +0530 Subject: [PATCH 151/279] fix: Contain all docs and related in docs folder The package.json and pnpm-lock.yaml are not part of the main repo but specific to the docs. The workflow will now target this folder for running. --- .github/workflows/publish_docs.yml | 13 +++++++++---- package.json => docs/package.json | 0 pnpm-lock.yaml => docs/pnpm-lock.yaml | 0 3 files changed, 9 insertions(+), 4 deletions(-) rename package.json => docs/package.json (100%) rename pnpm-lock.yaml => docs/pnpm-lock.yaml (100%) diff --git a/.github/workflows/publish_docs.yml b/.github/workflows/publish_docs.yml index f8cd75f5..df467e00 100644 --- a/.github/workflows/publish_docs.yml +++ b/.github/workflows/publish_docs.yml @@ -2,7 +2,7 @@ name: Deploy Frappe Docker Docs to GitHub Pages on: push: - branches: [docs] + branches: [docs-v2] paths: - "docs/**" - ".github/workflows/publish_docs.yml" @@ -13,6 +13,10 @@ permissions: pages: write id-token: write +defaults: + run: + working-directory: ./docs + concurrency: group: pages cancel-in-progress: true @@ -26,7 +30,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Install pnpm uses: pnpm/action-setup@v4 @@ -34,10 +38,11 @@ jobs: version: 10 - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: node-version: ${{ matrix.node-version }} cache: "pnpm" + cache-dependency-path: ./docs - name: Install dependencies run: pnpm i --frozen-lockfile @@ -46,7 +51,7 @@ jobs: run: pnpm docs:build - name: Upload artifact - uses: actions/upload-pages-artifact@v3 + uses: actions/upload-pages-artifact@v4 with: path: docs/.vitepress/dist diff --git a/package.json b/docs/package.json similarity index 100% rename from package.json rename to docs/package.json diff --git a/pnpm-lock.yaml b/docs/pnpm-lock.yaml similarity index 100% rename from pnpm-lock.yaml rename to docs/pnpm-lock.yaml From cab78405cc8f77494d95ce3b2a1e786336eb2f11 Mon Sep 17 00:00:00 2001 From: adithya Date: Sat, 7 Feb 2026 00:17:38 +0530 Subject: [PATCH 152/279] refactor: Moving md files to src for clarity --- docs/.vitepress/config.mts | 5 +++-- docs/package.json | 11 ++++++----- .../01-choosing-a-deployment-method.md | 4 ++-- .../01-getting-started/02-docker-immutability.md | 0 docs/{ => src}/01-getting-started/03-arm64.md | 0 .../01-getting-started/04-single-compose-setup.md | 0 docs/{ => src}/01-getting-started/index.md | 0 docs/{ => src}/02-setup/01-overview.md | 0 docs/{ => src}/02-setup/02-build-setup.md | 0 docs/{ => src}/02-setup/03-start-setup.md | 0 docs/{ => src}/02-setup/04-env-variables.md | 0 docs/{ => src}/02-setup/05-overrides.md | 0 docs/{ => src}/02-setup/06-setup-examples.md | 0 docs/{ => src}/02-setup/07-single-server-example.md | 0 .../02-setup/08-single-server-nginxproxy-example.md | 0 docs/{ => src}/02-setup/index.md | 0 docs/{ => src}/03-production/01-tls-ssl-setup.md | 0 docs/{ => src}/03-production/02-backup-strategy.md | 0 docs/{ => src}/03-production/03-multi-tenancy.md | 0 .../03-production/04-nginx-proxy-acme-companion.md | 0 docs/{ => src}/03-production/05-caddy-https.md | 0 docs/{ => src}/03-production/index.md | 0 docs/{ => src}/04-operations/01-site-operations.md | 0 docs/{ => src}/04-operations/index.md | 0 docs/{ => src}/05-development/01-development.md | 0 docs/{ => src}/05-development/02-debugging.md | 0 .../05-development/03-local-services-connection.md | 0 docs/{ => src}/05-development/index.md | 0 .../01-migrate-from-multi-image-setup.md | 0 .../06-migration/02-traefik-v3-migration.md | 0 docs/{ => src}/06-migration/index.md | 0 .../{ => src}/07-troubleshooting/01-troubleshoot.md | 0 .../02-windows-nginx-entrypoint-error.md | 0 docs/{ => src}/07-troubleshooting/index.md | 0 .../08-reference/01-build-version-10-images.md | 0 docs/{ => src}/08-reference/index.md | 0 docs/{ => src}/getting-started.md | 0 ...ocker Desktop Screenshot - Resources section.png | Bin ...Docker Manual Screenshot - Resources section.png | Bin docs/{ => src}/index.md | 0 40 files changed, 11 insertions(+), 9 deletions(-) rename docs/{ => src}/01-getting-started/01-choosing-a-deployment-method.md (96%) rename docs/{ => src}/01-getting-started/02-docker-immutability.md (100%) rename docs/{ => src}/01-getting-started/03-arm64.md (100%) rename docs/{ => src}/01-getting-started/04-single-compose-setup.md (100%) rename docs/{ => src}/01-getting-started/index.md (100%) rename docs/{ => src}/02-setup/01-overview.md (100%) rename docs/{ => src}/02-setup/02-build-setup.md (100%) rename docs/{ => src}/02-setup/03-start-setup.md (100%) rename docs/{ => src}/02-setup/04-env-variables.md (100%) rename docs/{ => src}/02-setup/05-overrides.md (100%) rename docs/{ => src}/02-setup/06-setup-examples.md (100%) rename docs/{ => src}/02-setup/07-single-server-example.md (100%) rename docs/{ => src}/02-setup/08-single-server-nginxproxy-example.md (100%) rename docs/{ => src}/02-setup/index.md (100%) rename docs/{ => src}/03-production/01-tls-ssl-setup.md (100%) rename docs/{ => src}/03-production/02-backup-strategy.md (100%) rename docs/{ => src}/03-production/03-multi-tenancy.md (100%) rename docs/{ => src}/03-production/04-nginx-proxy-acme-companion.md (100%) rename docs/{ => src}/03-production/05-caddy-https.md (100%) rename docs/{ => src}/03-production/index.md (100%) rename docs/{ => src}/04-operations/01-site-operations.md (100%) rename docs/{ => src}/04-operations/index.md (100%) rename docs/{ => src}/05-development/01-development.md (100%) rename docs/{ => src}/05-development/02-debugging.md (100%) rename docs/{ => src}/05-development/03-local-services-connection.md (100%) rename docs/{ => src}/05-development/index.md (100%) rename docs/{ => src}/06-migration/01-migrate-from-multi-image-setup.md (100%) rename docs/{ => src}/06-migration/02-traefik-v3-migration.md (100%) rename docs/{ => src}/06-migration/index.md (100%) rename docs/{ => src}/07-troubleshooting/01-troubleshoot.md (100%) rename docs/{ => src}/07-troubleshooting/02-windows-nginx-entrypoint-error.md (100%) rename docs/{ => src}/07-troubleshooting/index.md (100%) rename docs/{ => src}/08-reference/01-build-version-10-images.md (100%) rename docs/{ => src}/08-reference/index.md (100%) rename docs/{ => src}/getting-started.md (100%) rename docs/{ => src}/images/Docker Desktop Screenshot - Resources section.png (100%) rename docs/{ => src}/images/Docker Manual Screenshot - Resources section.png (100%) rename docs/{ => src}/index.md (100%) diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts index 495139ae..42adf4b2 100644 --- a/docs/.vitepress/config.mts +++ b/docs/.vitepress/config.mts @@ -5,6 +5,7 @@ import { withSidebar } from "vitepress-sidebar"; const vitePressOptions = { title: "Frappe Docker Docs", description: "Frappe in a Container", + srcDir: "./src", base: "/frappe_docker/", themeConfig: { logo: "/frappe-docker.png", @@ -18,11 +19,11 @@ const vitePressOptions = { }; const vitePressSidebarOptions = { - documentRootPath: "./docs", + documentRootPath: ".", useTitleFromFrontmatter: true, useFolderTitleFromIndexFile: true, }; export default defineConfig( - withSidebar(vitePressOptions, vitePressSidebarOptions) + withSidebar(vitePressOptions, vitePressSidebarOptions), ); diff --git a/docs/package.json b/docs/package.json index a365f27f..32e71881 100644 --- a/docs/package.json +++ b/docs/package.json @@ -4,8 +4,9 @@ "vitepress-sidebar": "^1.33.1" }, "scripts": { - "docs:dev": "vitepress dev docs", - "docs:build": "vitepress build docs", - "docs:preview": "vitepress preview docs" - } -} \ No newline at end of file + "docs:dev": "vitepress dev", + "docs:build": "vitepress build", + "docs:preview": "vitepress preview" + }, + "packageManager": "pnpm@10.28.2+sha512.41872f037ad22f7348e3b1debbaf7e867cfd448f2726d9cf74c08f19507c31d2c8e7a11525b983febc2df640b5438dee6023ebb1f84ed43cc2d654d2bc326264" +} diff --git a/docs/01-getting-started/01-choosing-a-deployment-method.md b/docs/src/01-getting-started/01-choosing-a-deployment-method.md similarity index 96% rename from docs/01-getting-started/01-choosing-a-deployment-method.md rename to docs/src/01-getting-started/01-choosing-a-deployment-method.md index 11b39a8f..4b343c06 100644 --- a/docs/01-getting-started/01-choosing-a-deployment-method.md +++ b/docs/src/01-getting-started/01-choosing-a-deployment-method.md @@ -45,7 +45,7 @@ If you start with `pwd.yml`, you should expect to **throw the environment away** ## 2. VS Code Devcontainers – Local Development Setup -The development setup described in [`/docs/05-development`](../05-development) +The development setup described in [`/docs/05-development/development.md`](../05-development/01-development.md) uses **VS Code Devcontainers** to provide a **local Frappe development environment**. @@ -103,7 +103,7 @@ It uses: - The main `compose.yml` - Override files from the `overrides/` directory -Detailed instructions are available in [`/docs/02-setup`](../02-setup) +Detailed instructions are available in [`/docs/02-setup`](../02-setup/01-overview.md) ### Characteristics diff --git a/docs/01-getting-started/02-docker-immutability.md b/docs/src/01-getting-started/02-docker-immutability.md similarity index 100% rename from docs/01-getting-started/02-docker-immutability.md rename to docs/src/01-getting-started/02-docker-immutability.md diff --git a/docs/01-getting-started/03-arm64.md b/docs/src/01-getting-started/03-arm64.md similarity index 100% rename from docs/01-getting-started/03-arm64.md rename to docs/src/01-getting-started/03-arm64.md diff --git a/docs/01-getting-started/04-single-compose-setup.md b/docs/src/01-getting-started/04-single-compose-setup.md similarity index 100% rename from docs/01-getting-started/04-single-compose-setup.md rename to docs/src/01-getting-started/04-single-compose-setup.md diff --git a/docs/01-getting-started/index.md b/docs/src/01-getting-started/index.md similarity index 100% rename from docs/01-getting-started/index.md rename to docs/src/01-getting-started/index.md diff --git a/docs/02-setup/01-overview.md b/docs/src/02-setup/01-overview.md similarity index 100% rename from docs/02-setup/01-overview.md rename to docs/src/02-setup/01-overview.md diff --git a/docs/02-setup/02-build-setup.md b/docs/src/02-setup/02-build-setup.md similarity index 100% rename from docs/02-setup/02-build-setup.md rename to docs/src/02-setup/02-build-setup.md diff --git a/docs/02-setup/03-start-setup.md b/docs/src/02-setup/03-start-setup.md similarity index 100% rename from docs/02-setup/03-start-setup.md rename to docs/src/02-setup/03-start-setup.md diff --git a/docs/02-setup/04-env-variables.md b/docs/src/02-setup/04-env-variables.md similarity index 100% rename from docs/02-setup/04-env-variables.md rename to docs/src/02-setup/04-env-variables.md diff --git a/docs/02-setup/05-overrides.md b/docs/src/02-setup/05-overrides.md similarity index 100% rename from docs/02-setup/05-overrides.md rename to docs/src/02-setup/05-overrides.md diff --git a/docs/02-setup/06-setup-examples.md b/docs/src/02-setup/06-setup-examples.md similarity index 100% rename from docs/02-setup/06-setup-examples.md rename to docs/src/02-setup/06-setup-examples.md diff --git a/docs/02-setup/07-single-server-example.md b/docs/src/02-setup/07-single-server-example.md similarity index 100% rename from docs/02-setup/07-single-server-example.md rename to docs/src/02-setup/07-single-server-example.md diff --git a/docs/02-setup/08-single-server-nginxproxy-example.md b/docs/src/02-setup/08-single-server-nginxproxy-example.md similarity index 100% rename from docs/02-setup/08-single-server-nginxproxy-example.md rename to docs/src/02-setup/08-single-server-nginxproxy-example.md diff --git a/docs/02-setup/index.md b/docs/src/02-setup/index.md similarity index 100% rename from docs/02-setup/index.md rename to docs/src/02-setup/index.md diff --git a/docs/03-production/01-tls-ssl-setup.md b/docs/src/03-production/01-tls-ssl-setup.md similarity index 100% rename from docs/03-production/01-tls-ssl-setup.md rename to docs/src/03-production/01-tls-ssl-setup.md diff --git a/docs/03-production/02-backup-strategy.md b/docs/src/03-production/02-backup-strategy.md similarity index 100% rename from docs/03-production/02-backup-strategy.md rename to docs/src/03-production/02-backup-strategy.md diff --git a/docs/03-production/03-multi-tenancy.md b/docs/src/03-production/03-multi-tenancy.md similarity index 100% rename from docs/03-production/03-multi-tenancy.md rename to docs/src/03-production/03-multi-tenancy.md diff --git a/docs/03-production/04-nginx-proxy-acme-companion.md b/docs/src/03-production/04-nginx-proxy-acme-companion.md similarity index 100% rename from docs/03-production/04-nginx-proxy-acme-companion.md rename to docs/src/03-production/04-nginx-proxy-acme-companion.md diff --git a/docs/03-production/05-caddy-https.md b/docs/src/03-production/05-caddy-https.md similarity index 100% rename from docs/03-production/05-caddy-https.md rename to docs/src/03-production/05-caddy-https.md diff --git a/docs/03-production/index.md b/docs/src/03-production/index.md similarity index 100% rename from docs/03-production/index.md rename to docs/src/03-production/index.md diff --git a/docs/04-operations/01-site-operations.md b/docs/src/04-operations/01-site-operations.md similarity index 100% rename from docs/04-operations/01-site-operations.md rename to docs/src/04-operations/01-site-operations.md diff --git a/docs/04-operations/index.md b/docs/src/04-operations/index.md similarity index 100% rename from docs/04-operations/index.md rename to docs/src/04-operations/index.md diff --git a/docs/05-development/01-development.md b/docs/src/05-development/01-development.md similarity index 100% rename from docs/05-development/01-development.md rename to docs/src/05-development/01-development.md diff --git a/docs/05-development/02-debugging.md b/docs/src/05-development/02-debugging.md similarity index 100% rename from docs/05-development/02-debugging.md rename to docs/src/05-development/02-debugging.md diff --git a/docs/05-development/03-local-services-connection.md b/docs/src/05-development/03-local-services-connection.md similarity index 100% rename from docs/05-development/03-local-services-connection.md rename to docs/src/05-development/03-local-services-connection.md diff --git a/docs/05-development/index.md b/docs/src/05-development/index.md similarity index 100% rename from docs/05-development/index.md rename to docs/src/05-development/index.md diff --git a/docs/06-migration/01-migrate-from-multi-image-setup.md b/docs/src/06-migration/01-migrate-from-multi-image-setup.md similarity index 100% rename from docs/06-migration/01-migrate-from-multi-image-setup.md rename to docs/src/06-migration/01-migrate-from-multi-image-setup.md diff --git a/docs/06-migration/02-traefik-v3-migration.md b/docs/src/06-migration/02-traefik-v3-migration.md similarity index 100% rename from docs/06-migration/02-traefik-v3-migration.md rename to docs/src/06-migration/02-traefik-v3-migration.md diff --git a/docs/06-migration/index.md b/docs/src/06-migration/index.md similarity index 100% rename from docs/06-migration/index.md rename to docs/src/06-migration/index.md diff --git a/docs/07-troubleshooting/01-troubleshoot.md b/docs/src/07-troubleshooting/01-troubleshoot.md similarity index 100% rename from docs/07-troubleshooting/01-troubleshoot.md rename to docs/src/07-troubleshooting/01-troubleshoot.md diff --git a/docs/07-troubleshooting/02-windows-nginx-entrypoint-error.md b/docs/src/07-troubleshooting/02-windows-nginx-entrypoint-error.md similarity index 100% rename from docs/07-troubleshooting/02-windows-nginx-entrypoint-error.md rename to docs/src/07-troubleshooting/02-windows-nginx-entrypoint-error.md diff --git a/docs/07-troubleshooting/index.md b/docs/src/07-troubleshooting/index.md similarity index 100% rename from docs/07-troubleshooting/index.md rename to docs/src/07-troubleshooting/index.md diff --git a/docs/08-reference/01-build-version-10-images.md b/docs/src/08-reference/01-build-version-10-images.md similarity index 100% rename from docs/08-reference/01-build-version-10-images.md rename to docs/src/08-reference/01-build-version-10-images.md diff --git a/docs/08-reference/index.md b/docs/src/08-reference/index.md similarity index 100% rename from docs/08-reference/index.md rename to docs/src/08-reference/index.md diff --git a/docs/getting-started.md b/docs/src/getting-started.md similarity index 100% rename from docs/getting-started.md rename to docs/src/getting-started.md diff --git a/docs/images/Docker Desktop Screenshot - Resources section.png b/docs/src/images/Docker Desktop Screenshot - Resources section.png similarity index 100% rename from docs/images/Docker Desktop Screenshot - Resources section.png rename to docs/src/images/Docker Desktop Screenshot - Resources section.png diff --git a/docs/images/Docker Manual Screenshot - Resources section.png b/docs/src/images/Docker Manual Screenshot - Resources section.png similarity index 100% rename from docs/images/Docker Manual Screenshot - Resources section.png rename to docs/src/images/Docker Manual Screenshot - Resources section.png diff --git a/docs/index.md b/docs/src/index.md similarity index 100% rename from docs/index.md rename to docs/src/index.md From 2901865e74b8e2f5320547d2d2cbdf7d1be82bf3 Mon Sep 17 00:00:00 2001 From: adithya Date: Sat, 7 Feb 2026 00:23:45 +0530 Subject: [PATCH 153/279] fix: Frappe Docker logo moved public folder to docs. --- .github/workflows/publish_docs.yml | 2 +- docs/{ => src}/public/frappe-docker.png | Bin 2 files changed, 1 insertion(+), 1 deletion(-) rename docs/{ => src}/public/frappe-docker.png (100%) diff --git a/.github/workflows/publish_docs.yml b/.github/workflows/publish_docs.yml index df467e00..30683402 100644 --- a/.github/workflows/publish_docs.yml +++ b/.github/workflows/publish_docs.yml @@ -26,7 +26,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node-version: [20] + node-version: [24] steps: - name: Checkout diff --git a/docs/public/frappe-docker.png b/docs/src/public/frappe-docker.png similarity index 100% rename from docs/public/frappe-docker.png rename to docs/src/public/frappe-docker.png From b6247270125bbeb28eae891294141440a9b715da Mon Sep 17 00:00:00 2001 From: adithya Date: Sat, 7 Feb 2026 00:31:01 +0530 Subject: [PATCH 154/279] fix: Sidebar config issue Properly source the sidebar links --- docs/.vitepress/config.mts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts index 42adf4b2..403cb622 100644 --- a/docs/.vitepress/config.mts +++ b/docs/.vitepress/config.mts @@ -19,7 +19,7 @@ const vitePressOptions = { }; const vitePressSidebarOptions = { - documentRootPath: ".", + documentRootPath: "./src", useTitleFromFrontmatter: true, useFolderTitleFromIndexFile: true, }; From 98f83f96762ddbb2ae5da6f4d01c1cd1972d21c8 Mon Sep 17 00:00:00 2001 From: adithya Date: Sat, 7 Feb 2026 00:44:43 +0530 Subject: [PATCH 155/279] feat: added favicon --- docs/.vitepress/config.mts | 5 +++-- docs/src/public/favicon.png | Bin 0 -> 45163 bytes 2 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 docs/src/public/favicon.png diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts index 403cb622..dbd62a79 100644 --- a/docs/.vitepress/config.mts +++ b/docs/.vitepress/config.mts @@ -1,12 +1,13 @@ -import { defineConfig } from "vitepress"; +import { defineConfig, UserConfig } from "vitepress"; import { withSidebar } from "vitepress-sidebar"; // https://vitepress.dev/reference/site-config -const vitePressOptions = { +const vitePressOptions: UserConfig = { title: "Frappe Docker Docs", description: "Frappe in a Container", srcDir: "./src", base: "/frappe_docker/", + head: [["link", { rel: "icon", href: "/frappe_docker/favicon.png" }]], themeConfig: { logo: "/frappe-docker.png", // https://vitepress.dev/reference/default-theme-config diff --git a/docs/src/public/favicon.png b/docs/src/public/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..7f1138ab23a9ab37897d0ad4c4be60d64b03cfb9 GIT binary patch literal 45163 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 Vzu01V4C-=Zc+liP=Kixc{|ni Date: Sat, 7 Feb 2026 00:56:43 +0530 Subject: [PATCH 156/279] fix: Changed branch to `main` For creating pull request --- .github/workflows/publish_docs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish_docs.yml b/.github/workflows/publish_docs.yml index 30683402..d2f6c2b2 100644 --- a/.github/workflows/publish_docs.yml +++ b/.github/workflows/publish_docs.yml @@ -2,7 +2,7 @@ name: Deploy Frappe Docker Docs to GitHub Pages on: push: - branches: [docs-v2] + branches: [main] paths: - "docs/**" - ".github/workflows/publish_docs.yml" From 477376edc42c598887ceccdef353b0407c72508d Mon Sep 17 00:00:00 2001 From: adithya Date: Sat, 7 Feb 2026 01:02:15 +0530 Subject: [PATCH 157/279] refactor: Moved md files back to docs Refactor can be considered later if needed. --- docs/.vitepress/config.mts | 3 +-- .../01-choosing-a-deployment-method.md | 0 .../01-getting-started/02-docker-immutability.md | 0 docs/{src => }/01-getting-started/03-arm64.md | 0 .../01-getting-started/04-single-compose-setup.md | 0 docs/{src => }/01-getting-started/index.md | 0 docs/{src => }/02-setup/01-overview.md | 0 docs/{src => }/02-setup/02-build-setup.md | 0 docs/{src => }/02-setup/03-start-setup.md | 0 docs/{src => }/02-setup/04-env-variables.md | 0 docs/{src => }/02-setup/05-overrides.md | 0 docs/{src => }/02-setup/06-setup-examples.md | 0 docs/{src => }/02-setup/07-single-server-example.md | 0 .../02-setup/08-single-server-nginxproxy-example.md | 0 docs/{src => }/02-setup/index.md | 0 docs/{src => }/03-production/01-tls-ssl-setup.md | 0 docs/{src => }/03-production/02-backup-strategy.md | 0 docs/{src => }/03-production/03-multi-tenancy.md | 0 .../03-production/04-nginx-proxy-acme-companion.md | 0 docs/{src => }/03-production/05-caddy-https.md | 0 docs/{src => }/03-production/index.md | 0 docs/{src => }/04-operations/01-site-operations.md | 0 docs/{src => }/04-operations/index.md | 0 docs/{src => }/05-development/01-development.md | 0 docs/{src => }/05-development/02-debugging.md | 0 .../05-development/03-local-services-connection.md | 0 docs/{src => }/05-development/index.md | 0 .../01-migrate-from-multi-image-setup.md | 0 .../06-migration/02-traefik-v3-migration.md | 0 docs/{src => }/06-migration/index.md | 0 .../{src => }/07-troubleshooting/01-troubleshoot.md | 0 .../02-windows-nginx-entrypoint-error.md | 0 docs/{src => }/07-troubleshooting/index.md | 0 .../08-reference/01-build-version-10-images.md | 0 docs/{src => }/08-reference/index.md | 0 docs/{src => }/getting-started.md | 0 ...ocker Desktop Screenshot - Resources section.png | Bin ...Docker Manual Screenshot - Resources section.png | Bin docs/{src => }/index.md | 0 docs/{src => }/public/favicon.png | Bin docs/{src => }/public/frappe-docker.png | Bin 41 files changed, 1 insertion(+), 2 deletions(-) rename docs/{src => }/01-getting-started/01-choosing-a-deployment-method.md (100%) rename docs/{src => }/01-getting-started/02-docker-immutability.md (100%) rename docs/{src => }/01-getting-started/03-arm64.md (100%) rename docs/{src => }/01-getting-started/04-single-compose-setup.md (100%) rename docs/{src => }/01-getting-started/index.md (100%) rename docs/{src => }/02-setup/01-overview.md (100%) rename docs/{src => }/02-setup/02-build-setup.md (100%) rename docs/{src => }/02-setup/03-start-setup.md (100%) rename docs/{src => }/02-setup/04-env-variables.md (100%) rename docs/{src => }/02-setup/05-overrides.md (100%) rename docs/{src => }/02-setup/06-setup-examples.md (100%) rename docs/{src => }/02-setup/07-single-server-example.md (100%) rename docs/{src => }/02-setup/08-single-server-nginxproxy-example.md (100%) rename docs/{src => }/02-setup/index.md (100%) rename docs/{src => }/03-production/01-tls-ssl-setup.md (100%) rename docs/{src => }/03-production/02-backup-strategy.md (100%) rename docs/{src => }/03-production/03-multi-tenancy.md (100%) rename docs/{src => }/03-production/04-nginx-proxy-acme-companion.md (100%) rename docs/{src => }/03-production/05-caddy-https.md (100%) rename docs/{src => }/03-production/index.md (100%) rename docs/{src => }/04-operations/01-site-operations.md (100%) rename docs/{src => }/04-operations/index.md (100%) rename docs/{src => }/05-development/01-development.md (100%) rename docs/{src => }/05-development/02-debugging.md (100%) rename docs/{src => }/05-development/03-local-services-connection.md (100%) rename docs/{src => }/05-development/index.md (100%) rename docs/{src => }/06-migration/01-migrate-from-multi-image-setup.md (100%) rename docs/{src => }/06-migration/02-traefik-v3-migration.md (100%) rename docs/{src => }/06-migration/index.md (100%) rename docs/{src => }/07-troubleshooting/01-troubleshoot.md (100%) rename docs/{src => }/07-troubleshooting/02-windows-nginx-entrypoint-error.md (100%) rename docs/{src => }/07-troubleshooting/index.md (100%) rename docs/{src => }/08-reference/01-build-version-10-images.md (100%) rename docs/{src => }/08-reference/index.md (100%) rename docs/{src => }/getting-started.md (100%) rename docs/{src => }/images/Docker Desktop Screenshot - Resources section.png (100%) rename docs/{src => }/images/Docker Manual Screenshot - Resources section.png (100%) rename docs/{src => }/index.md (100%) rename docs/{src => }/public/favicon.png (100%) rename docs/{src => }/public/frappe-docker.png (100%) diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts index dbd62a79..192c7ca0 100644 --- a/docs/.vitepress/config.mts +++ b/docs/.vitepress/config.mts @@ -5,7 +5,6 @@ import { withSidebar } from "vitepress-sidebar"; const vitePressOptions: UserConfig = { title: "Frappe Docker Docs", description: "Frappe in a Container", - srcDir: "./src", base: "/frappe_docker/", head: [["link", { rel: "icon", href: "/frappe_docker/favicon.png" }]], themeConfig: { @@ -20,7 +19,7 @@ const vitePressOptions: UserConfig = { }; const vitePressSidebarOptions = { - documentRootPath: "./src", + documentRootPath: ".", useTitleFromFrontmatter: true, useFolderTitleFromIndexFile: true, }; diff --git a/docs/src/01-getting-started/01-choosing-a-deployment-method.md b/docs/01-getting-started/01-choosing-a-deployment-method.md similarity index 100% rename from docs/src/01-getting-started/01-choosing-a-deployment-method.md rename to docs/01-getting-started/01-choosing-a-deployment-method.md diff --git a/docs/src/01-getting-started/02-docker-immutability.md b/docs/01-getting-started/02-docker-immutability.md similarity index 100% rename from docs/src/01-getting-started/02-docker-immutability.md rename to docs/01-getting-started/02-docker-immutability.md diff --git a/docs/src/01-getting-started/03-arm64.md b/docs/01-getting-started/03-arm64.md similarity index 100% rename from docs/src/01-getting-started/03-arm64.md rename to docs/01-getting-started/03-arm64.md diff --git a/docs/src/01-getting-started/04-single-compose-setup.md b/docs/01-getting-started/04-single-compose-setup.md similarity index 100% rename from docs/src/01-getting-started/04-single-compose-setup.md rename to docs/01-getting-started/04-single-compose-setup.md diff --git a/docs/src/01-getting-started/index.md b/docs/01-getting-started/index.md similarity index 100% rename from docs/src/01-getting-started/index.md rename to docs/01-getting-started/index.md diff --git a/docs/src/02-setup/01-overview.md b/docs/02-setup/01-overview.md similarity index 100% rename from docs/src/02-setup/01-overview.md rename to docs/02-setup/01-overview.md diff --git a/docs/src/02-setup/02-build-setup.md b/docs/02-setup/02-build-setup.md similarity index 100% rename from docs/src/02-setup/02-build-setup.md rename to docs/02-setup/02-build-setup.md diff --git a/docs/src/02-setup/03-start-setup.md b/docs/02-setup/03-start-setup.md similarity index 100% rename from docs/src/02-setup/03-start-setup.md rename to docs/02-setup/03-start-setup.md diff --git a/docs/src/02-setup/04-env-variables.md b/docs/02-setup/04-env-variables.md similarity index 100% rename from docs/src/02-setup/04-env-variables.md rename to docs/02-setup/04-env-variables.md diff --git a/docs/src/02-setup/05-overrides.md b/docs/02-setup/05-overrides.md similarity index 100% rename from docs/src/02-setup/05-overrides.md rename to docs/02-setup/05-overrides.md diff --git a/docs/src/02-setup/06-setup-examples.md b/docs/02-setup/06-setup-examples.md similarity index 100% rename from docs/src/02-setup/06-setup-examples.md rename to docs/02-setup/06-setup-examples.md diff --git a/docs/src/02-setup/07-single-server-example.md b/docs/02-setup/07-single-server-example.md similarity index 100% rename from docs/src/02-setup/07-single-server-example.md rename to docs/02-setup/07-single-server-example.md diff --git a/docs/src/02-setup/08-single-server-nginxproxy-example.md b/docs/02-setup/08-single-server-nginxproxy-example.md similarity index 100% rename from docs/src/02-setup/08-single-server-nginxproxy-example.md rename to docs/02-setup/08-single-server-nginxproxy-example.md diff --git a/docs/src/02-setup/index.md b/docs/02-setup/index.md similarity index 100% rename from docs/src/02-setup/index.md rename to docs/02-setup/index.md diff --git a/docs/src/03-production/01-tls-ssl-setup.md b/docs/03-production/01-tls-ssl-setup.md similarity index 100% rename from docs/src/03-production/01-tls-ssl-setup.md rename to docs/03-production/01-tls-ssl-setup.md diff --git a/docs/src/03-production/02-backup-strategy.md b/docs/03-production/02-backup-strategy.md similarity index 100% rename from docs/src/03-production/02-backup-strategy.md rename to docs/03-production/02-backup-strategy.md diff --git a/docs/src/03-production/03-multi-tenancy.md b/docs/03-production/03-multi-tenancy.md similarity index 100% rename from docs/src/03-production/03-multi-tenancy.md rename to docs/03-production/03-multi-tenancy.md diff --git a/docs/src/03-production/04-nginx-proxy-acme-companion.md b/docs/03-production/04-nginx-proxy-acme-companion.md similarity index 100% rename from docs/src/03-production/04-nginx-proxy-acme-companion.md rename to docs/03-production/04-nginx-proxy-acme-companion.md diff --git a/docs/src/03-production/05-caddy-https.md b/docs/03-production/05-caddy-https.md similarity index 100% rename from docs/src/03-production/05-caddy-https.md rename to docs/03-production/05-caddy-https.md diff --git a/docs/src/03-production/index.md b/docs/03-production/index.md similarity index 100% rename from docs/src/03-production/index.md rename to docs/03-production/index.md diff --git a/docs/src/04-operations/01-site-operations.md b/docs/04-operations/01-site-operations.md similarity index 100% rename from docs/src/04-operations/01-site-operations.md rename to docs/04-operations/01-site-operations.md diff --git a/docs/src/04-operations/index.md b/docs/04-operations/index.md similarity index 100% rename from docs/src/04-operations/index.md rename to docs/04-operations/index.md diff --git a/docs/src/05-development/01-development.md b/docs/05-development/01-development.md similarity index 100% rename from docs/src/05-development/01-development.md rename to docs/05-development/01-development.md diff --git a/docs/src/05-development/02-debugging.md b/docs/05-development/02-debugging.md similarity index 100% rename from docs/src/05-development/02-debugging.md rename to docs/05-development/02-debugging.md diff --git a/docs/src/05-development/03-local-services-connection.md b/docs/05-development/03-local-services-connection.md similarity index 100% rename from docs/src/05-development/03-local-services-connection.md rename to docs/05-development/03-local-services-connection.md diff --git a/docs/src/05-development/index.md b/docs/05-development/index.md similarity index 100% rename from docs/src/05-development/index.md rename to docs/05-development/index.md diff --git a/docs/src/06-migration/01-migrate-from-multi-image-setup.md b/docs/06-migration/01-migrate-from-multi-image-setup.md similarity index 100% rename from docs/src/06-migration/01-migrate-from-multi-image-setup.md rename to docs/06-migration/01-migrate-from-multi-image-setup.md diff --git a/docs/src/06-migration/02-traefik-v3-migration.md b/docs/06-migration/02-traefik-v3-migration.md similarity index 100% rename from docs/src/06-migration/02-traefik-v3-migration.md rename to docs/06-migration/02-traefik-v3-migration.md diff --git a/docs/src/06-migration/index.md b/docs/06-migration/index.md similarity index 100% rename from docs/src/06-migration/index.md rename to docs/06-migration/index.md diff --git a/docs/src/07-troubleshooting/01-troubleshoot.md b/docs/07-troubleshooting/01-troubleshoot.md similarity index 100% rename from docs/src/07-troubleshooting/01-troubleshoot.md rename to docs/07-troubleshooting/01-troubleshoot.md diff --git a/docs/src/07-troubleshooting/02-windows-nginx-entrypoint-error.md b/docs/07-troubleshooting/02-windows-nginx-entrypoint-error.md similarity index 100% rename from docs/src/07-troubleshooting/02-windows-nginx-entrypoint-error.md rename to docs/07-troubleshooting/02-windows-nginx-entrypoint-error.md diff --git a/docs/src/07-troubleshooting/index.md b/docs/07-troubleshooting/index.md similarity index 100% rename from docs/src/07-troubleshooting/index.md rename to docs/07-troubleshooting/index.md diff --git a/docs/src/08-reference/01-build-version-10-images.md b/docs/08-reference/01-build-version-10-images.md similarity index 100% rename from docs/src/08-reference/01-build-version-10-images.md rename to docs/08-reference/01-build-version-10-images.md diff --git a/docs/src/08-reference/index.md b/docs/08-reference/index.md similarity index 100% rename from docs/src/08-reference/index.md rename to docs/08-reference/index.md diff --git a/docs/src/getting-started.md b/docs/getting-started.md similarity index 100% rename from docs/src/getting-started.md rename to docs/getting-started.md diff --git a/docs/src/images/Docker Desktop Screenshot - Resources section.png b/docs/images/Docker Desktop Screenshot - Resources section.png similarity index 100% rename from docs/src/images/Docker Desktop Screenshot - Resources section.png rename to docs/images/Docker Desktop Screenshot - Resources section.png diff --git a/docs/src/images/Docker Manual Screenshot - Resources section.png b/docs/images/Docker Manual Screenshot - Resources section.png similarity index 100% rename from docs/src/images/Docker Manual Screenshot - Resources section.png rename to docs/images/Docker Manual Screenshot - Resources section.png diff --git a/docs/src/index.md b/docs/index.md similarity index 100% rename from docs/src/index.md rename to docs/index.md diff --git a/docs/src/public/favicon.png b/docs/public/favicon.png similarity index 100% rename from docs/src/public/favicon.png rename to docs/public/favicon.png diff --git a/docs/src/public/frappe-docker.png b/docs/public/frappe-docker.png similarity index 100% rename from docs/src/public/frappe-docker.png rename to docs/public/frappe-docker.png From 208aa7b7f4203da622a8fae3f53c714050581771 Mon Sep 17 00:00:00 2001 From: adithya Date: Sat, 7 Feb 2026 01:07:38 +0530 Subject: [PATCH 158/279] fix: Header fix Header in TLS / SSL setup was accidentally reverted to older one. Now replaced with the new one. --- docs/03-production/01-tls-ssl-setup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/03-production/01-tls-ssl-setup.md b/docs/03-production/01-tls-ssl-setup.md index e2ea2e0e..91104455 100644 --- a/docs/03-production/01-tls-ssl-setup.md +++ b/docs/03-production/01-tls-ssl-setup.md @@ -2,7 +2,7 @@ title: TLS/SSL Setup Overview --- -# Accessing ERPNext through https on local deployment +# TLS/SSL Setup Overview Frappe Docker supports multiple TLS/SSL approaches. Choose the one that matches your routing needs and where you want the proxy to run. From bb06d6bb092ad22c5c0737eac63d74ef2d08ddd2 Mon Sep 17 00:00:00 2001 From: adithya Date: Sat, 7 Feb 2026 01:23:54 +0530 Subject: [PATCH 159/279] fix: Added missing title metadata New files didn't have YAML metadata, it is added now. --- docs/01-getting-started/01-choosing-a-deployment-method.md | 4 ++++ docs/01-getting-started/02-docker-immutability.md | 4 ++++ docs/02-setup/08-single-server-nginxproxy-example.md | 4 ++++ docs/03-production/04-nginx-proxy-acme-companion.md | 4 ++++ docs/03-production/05-caddy-https.md | 4 ++++ docs/06-migration/02-traefik-v3-migration.md | 4 ++++ 6 files changed, 24 insertions(+) diff --git a/docs/01-getting-started/01-choosing-a-deployment-method.md b/docs/01-getting-started/01-choosing-a-deployment-method.md index 4b343c06..409a50be 100644 --- a/docs/01-getting-started/01-choosing-a-deployment-method.md +++ b/docs/01-getting-started/01-choosing-a-deployment-method.md @@ -1,3 +1,7 @@ +--- +title: Choosing a Method +--- + # Choosing a Deployment or Development Method This repository (`frappe_docker`) supports **multiple ways to run Frappe using Docker**. diff --git a/docs/01-getting-started/02-docker-immutability.md b/docs/01-getting-started/02-docker-immutability.md index 38a82330..c42ba65d 100644 --- a/docs/01-getting-started/02-docker-immutability.md +++ b/docs/01-getting-started/02-docker-immutability.md @@ -1,3 +1,7 @@ +--- +title: Docker Immutability +--- + # Important Concept: Immutability and Persistence A frequent source of confusion is how **Docker-based Frappe deployments handle persistence**. diff --git a/docs/02-setup/08-single-server-nginxproxy-example.md b/docs/02-setup/08-single-server-nginxproxy-example.md index ec9ef913..0049e39f 100644 --- a/docs/02-setup/08-single-server-nginxproxy-example.md +++ b/docs/02-setup/08-single-server-nginxproxy-example.md @@ -1,3 +1,7 @@ +--- +title: Single Server Example +--- + # Single Server Example (nginx-proxy + acme-companion) This guide demonstrates a single-server setup using nginx-proxy and acme-companion for HTTPS. It is best for a small number of hostnames and a single bench. If you need multiple benches or advanced routing, use the Traefik-based example instead. diff --git a/docs/03-production/04-nginx-proxy-acme-companion.md b/docs/03-production/04-nginx-proxy-acme-companion.md index 15c474eb..70a0e223 100644 --- a/docs/03-production/04-nginx-proxy-acme-companion.md +++ b/docs/03-production/04-nginx-proxy-acme-companion.md @@ -1,3 +1,7 @@ +--- +title: NGINX and ACME Companion +--- + # nginx-proxy + acme-companion (HTTPS) This guide explains how to use nginx-proxy with acme-companion to provide HTTPS for a Frappe Docker stack. diff --git a/docs/03-production/05-caddy-https.md b/docs/03-production/05-caddy-https.md index a8683c5d..45aba8cc 100644 --- a/docs/03-production/05-caddy-https.md +++ b/docs/03-production/05-caddy-https.md @@ -1,3 +1,7 @@ +--- +title: Caddy with HTTPS +--- + # Caddy reverse proxy (local HTTPS) This guide shows how to use Caddy as an external reverse proxy in front of the frontend container. It is most useful for local HTTPS or internal networks. diff --git a/docs/06-migration/02-traefik-v3-migration.md b/docs/06-migration/02-traefik-v3-migration.md index cb0eee11..cb116e23 100644 --- a/docs/06-migration/02-traefik-v3-migration.md +++ b/docs/06-migration/02-traefik-v3-migration.md @@ -1,3 +1,7 @@ +--- +title: Migrate Traefik from v2 to v3 +--- + # Migrate an existing Traefik v2 instance to v3 Use this guide if you already run Traefik v2 with `frappe_docker` and want to upgrade to v3. It focuses on the image upgrade and the v3 routing rule changes that affect existing setups. From f4faecc1d621edc20049bdc74c98705194d0676d Mon Sep 17 00:00:00 2001 From: adithya Date: Tue, 10 Feb 2026 01:15:30 +0530 Subject: [PATCH 160/279] feat: Added Contribution Guide The README.md gives a brief overview about how to contribute to documentation, and more detailed isntructions specific to VitePress is added as a new page under References. --- CONTRIBUTING.md | 20 ++++++++- docs/08-reference/02-configuring-vitepress.md | 45 +++++++++++++++++++ 2 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 docs/08-reference/02-configuring-vitepress.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3389cfe0..23018349 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -102,7 +102,25 @@ pytest # Documentation -Place relevant markdown files in the `docs` directory and index them in README.md located at the root of repo. +Documentation is written as markdown files, and placed inside the `docs/` directory. There are multiple sub directories under `docs/`, and be sure to place the `.md` file in the relevant sub directory if you are adding a new page. + +If you want to include any image in the markdown file, place them in the `docs/images/` folder, and add a relative link in the `.md` file. + +Frappe Docker also have a static site version of the documentation, which is made using the same `.md` files in the `docs/` directory. Build pipeline uses [VitePress](https://vitepress.dev/) as the Static Site builder, which is a JavaScript (TypeScript) static site builder. Note that to contribute to the documentation JavaScript or VitePress knowledge is not needed. Updating the `.md` file is enough. + +The only additional content needed that is specific to VitePress, is a ['frontmatter'](https://vitepress.dev/guide/frontmatter#frontmatter). Frontmatter is like the `metadata` or `config` of that specific `.md` file, added at the beginning of the file and enclosed in `---`. For example, the frontmatter can include a friendly title, author, date of publishing, etc. A more detailed overview on what is frontmatter can be found in this [blog](https://www.seancdavis.com/posts/wtf-is-frontmatter/). + +In this project only one field is used in the frontmatter. The `title` field. This is used to specify the title of the page shown in the sidebar, which is either same or a simpler and smaller version of the first heading `#` of the page. To add the required frontmatter just add a block at the beginning of the `.md` file as shown below + +```yaml +--- +title: +--- +``` + +In case of any doubt, just refer to any of the existing `.md` file. Also checkout the Markdown section in the VitePress documentation to see some additional features supported by VitePress: [Markdown Extensions](https://vitepress.dev/guide/markdown). Be careful not to break compatibility with what is supported by GitHub markdown. It is recommended to keep the documentation simple. + +If you want details on how to configure or update VitePress specific settings and and functionalities, refer this page: [Configuring VitePress](https://github.com/frappe/frappe_docker/blob/main/docs/08-reference/02-configuring-vitepress.md) # Frappe and ERPNext updates diff --git a/docs/08-reference/02-configuring-vitepress.md b/docs/08-reference/02-configuring-vitepress.md new file mode 100644 index 00000000..9e396e35 --- /dev/null +++ b/docs/08-reference/02-configuring-vitepress.md @@ -0,0 +1,45 @@ +--- +title: Configuring VitePress +--- + +# Configuring VitePress + +To modify any VitePress related settings, a JavaScript development environment is needed. Everything related to VitePress is contained in the `docs/` folder. + +## Prerequisites + +1. Node.js v24 or above is recommended. To install and manage Node.js [nvm](https://github.com/nvm-sh/nvm) is the preferred way for Linux and MacOS. For Windows either official installer or [fnm](https://github.com/Schniz/fnm). +2. pnpm package manager, v10.28 or above. Easiest way to install pnpm is using [corepack](https://pnpm.io/installation#using-corepack) which is part of Node.js. + +## Development + +To start a development environment, + +1. Navigate to `/docs` directory in the terminal + +```sh +cd docs +``` + +2. Install dependencies + +```sh +pnpm install +``` + +3. Start the development server + +```sh +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. + +## 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. +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`. +5. To auto populate the sidebar, a plugin called 'VitePress Sidebar' is used. The `config.mts` also include config for this plugin. More details can be found in the [documentation page](https://vitepress-sidebar.cdget.com/guide/getting-started). +6. Each subfolder has an `index.md` file. This is used to specify the group heading of the pages in the sidebar. From d433f52e9a47507b92202b1663955ea766f1f1f5 Mon Sep 17 00:00:00 2001 From: adithya Date: Mon, 16 Mar 2026 00:01:11 +0530 Subject: [PATCH 161/279] ore: VitePress version bump --- docs/package.json | 2 +- docs/pnpm-lock.yaml | 910 ++++++++++++++++++++++---------------------- 2 files changed, 454 insertions(+), 458 deletions(-) diff --git a/docs/package.json b/docs/package.json index 32e71881..73b65329 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "devDependencies": { - "vitepress": "2.0.0-alpha.15", + "vitepress": "2.0.0-alpha.16", "vitepress-sidebar": "^1.33.1" }, "scripts": { diff --git a/docs/pnpm-lock.yaml b/docs/pnpm-lock.yaml index d382bcdb..9881ec77 100644 --- a/docs/pnpm-lock.yaml +++ b/docs/pnpm-lock.yaml @@ -9,8 +9,8 @@ importers: .: devDependencies: vitepress: - specifier: 2.0.0-alpha.15 - version: 2.0.0-alpha.15(postcss@8.5.6) + specifier: 2.0.0-alpha.16 + version: 2.0.0-alpha.16(postcss@8.5.8) vitepress-sidebar: specifier: ^1.33.1 version: 1.33.1 @@ -25,179 +25,182 @@ packages: resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} engines: {node: '>=6.9.0'} - '@babel/parser@7.28.5': - resolution: {integrity: sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==} + '@babel/parser@7.29.0': + resolution: {integrity: sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==} engines: {node: '>=6.0.0'} hasBin: true - '@babel/types@7.28.5': - resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==} + '@babel/types@7.29.0': + resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} engines: {node: '>=6.9.0'} - '@docsearch/css@4.3.2': - resolution: {integrity: sha512-K3Yhay9MgkBjJJ0WEL5MxnACModX9xuNt3UlQQkDEDZJZ0+aeWKtOkxHNndMRkMBnHdYvQjxkm6mdlneOtU1IQ==} + '@docsearch/css@4.6.0': + resolution: {integrity: sha512-YlcAimkXclvqta47g47efzCM5CFxDwv2ClkDfEs/fC/Ak0OxPH2b3czwa4o8O1TRBf+ujFF2RiUwszz2fPVNJQ==} - '@docsearch/js@4.3.2': - resolution: {integrity: sha512-xdfpPXMgKRY9EW7U1vtY7gLKbLZFa9ed+t0Dacquq8zXBqAlH9HlUf0h4Mhxm0xatsVeMaIR2wr/u6g0GsZyQw==} + '@docsearch/js@4.6.0': + resolution: {integrity: sha512-9/rbgkm/BgTq46cwxIohvSAz3koOFjnPpg0mwkJItAfzKbQIj+310PvwtgUY1YITDuGCag6yOL50GW2DBkaaBw==} - '@esbuild/aix-ppc64@0.25.12': - resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==} + '@docsearch/sidepanel-js@4.6.0': + resolution: {integrity: sha512-lFT5KLwlzUmpoGArCScNoK41l9a22JYsEPwBzMrz+/ILVR5Ax87UphCuiyDFQWEvEmbwzn/kJx5W/O5BUlN1Rw==} + + '@esbuild/aix-ppc64@0.27.4': + resolution: {integrity: sha512-cQPwL2mp2nSmHHJlCyoXgHGhbEPMrEEU5xhkcy3Hs/O7nGZqEpZ2sUtLaL9MORLtDfRvVl2/3PAuEkYZH0Ty8Q==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] - '@esbuild/android-arm64@0.25.12': - resolution: {integrity: sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==} + '@esbuild/android-arm64@0.27.4': + resolution: {integrity: sha512-gdLscB7v75wRfu7QSm/zg6Rx29VLdy9eTr2t44sfTW7CxwAtQghZ4ZnqHk3/ogz7xao0QAgrkradbBzcqFPasw==} engines: {node: '>=18'} cpu: [arm64] os: [android] - '@esbuild/android-arm@0.25.12': - resolution: {integrity: sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==} + '@esbuild/android-arm@0.27.4': + resolution: {integrity: sha512-X9bUgvxiC8CHAGKYufLIHGXPJWnr0OCdR0anD2e21vdvgCI8lIfqFbnoeOz7lBjdrAGUhqLZLcQo6MLhTO2DKQ==} engines: {node: '>=18'} cpu: [arm] os: [android] - '@esbuild/android-x64@0.25.12': - resolution: {integrity: sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==} + '@esbuild/android-x64@0.27.4': + resolution: {integrity: sha512-PzPFnBNVF292sfpfhiyiXCGSn9HZg5BcAz+ivBuSsl6Rk4ga1oEXAamhOXRFyMcjwr2DVtm40G65N3GLeH1Lvw==} engines: {node: '>=18'} cpu: [x64] os: [android] - '@esbuild/darwin-arm64@0.25.12': - resolution: {integrity: sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==} + '@esbuild/darwin-arm64@0.27.4': + resolution: {integrity: sha512-b7xaGIwdJlht8ZFCvMkpDN6uiSmnxxK56N2GDTMYPr2/gzvfdQN8rTfBsvVKmIVY/X7EM+/hJKEIbbHs9oA4tQ==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] - '@esbuild/darwin-x64@0.25.12': - resolution: {integrity: sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==} + '@esbuild/darwin-x64@0.27.4': + resolution: {integrity: sha512-sR+OiKLwd15nmCdqpXMnuJ9W2kpy0KigzqScqHI3Hqwr7IXxBp3Yva+yJwoqh7rE8V77tdoheRYataNKL4QrPw==} engines: {node: '>=18'} cpu: [x64] os: [darwin] - '@esbuild/freebsd-arm64@0.25.12': - resolution: {integrity: sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==} + '@esbuild/freebsd-arm64@0.27.4': + resolution: {integrity: sha512-jnfpKe+p79tCnm4GVav68A7tUFeKQwQyLgESwEAUzyxk/TJr4QdGog9sqWNcUbr/bZt/O/HXouspuQDd9JxFSw==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-x64@0.25.12': - resolution: {integrity: sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==} + '@esbuild/freebsd-x64@0.27.4': + resolution: {integrity: sha512-2kb4ceA/CpfUrIcTUl1wrP/9ad9Atrp5J94Lq69w7UwOMolPIGrfLSvAKJp0RTvkPPyn6CIWrNy13kyLikZRZQ==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] - '@esbuild/linux-arm64@0.25.12': - resolution: {integrity: sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==} + '@esbuild/linux-arm64@0.27.4': + resolution: {integrity: sha512-7nQOttdzVGth1iz57kxg9uCz57dxQLHWxopL6mYuYthohPKEK0vU0C3O21CcBK6KDlkYVcnDXY099HcCDXd9dA==} engines: {node: '>=18'} cpu: [arm64] os: [linux] - '@esbuild/linux-arm@0.25.12': - resolution: {integrity: sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==} + '@esbuild/linux-arm@0.27.4': + resolution: {integrity: sha512-aBYgcIxX/wd5n2ys0yESGeYMGF+pv6g0DhZr3G1ZG4jMfruU9Tl1i2Z+Wnj9/KjGz1lTLCcorqE2viePZqj4Eg==} engines: {node: '>=18'} cpu: [arm] os: [linux] - '@esbuild/linux-ia32@0.25.12': - resolution: {integrity: sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==} + '@esbuild/linux-ia32@0.27.4': + resolution: {integrity: sha512-oPtixtAIzgvzYcKBQM/qZ3R+9TEUd1aNJQu0HhGyqtx6oS7qTpvjheIWBbes4+qu1bNlo2V4cbkISr8q6gRBFA==} engines: {node: '>=18'} cpu: [ia32] os: [linux] - '@esbuild/linux-loong64@0.25.12': - resolution: {integrity: sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==} + '@esbuild/linux-loong64@0.27.4': + resolution: {integrity: sha512-8mL/vh8qeCoRcFH2nM8wm5uJP+ZcVYGGayMavi8GmRJjuI3g1v6Z7Ni0JJKAJW+m0EtUuARb6Lmp4hMjzCBWzA==} engines: {node: '>=18'} cpu: [loong64] os: [linux] - '@esbuild/linux-mips64el@0.25.12': - resolution: {integrity: sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==} + '@esbuild/linux-mips64el@0.27.4': + resolution: {integrity: sha512-1RdrWFFiiLIW7LQq9Q2NES+HiD4NyT8Itj9AUeCl0IVCA459WnPhREKgwrpaIfTOe+/2rdntisegiPWn/r/aAw==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] - '@esbuild/linux-ppc64@0.25.12': - resolution: {integrity: sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==} + '@esbuild/linux-ppc64@0.27.4': + resolution: {integrity: sha512-tLCwNG47l3sd9lpfyx9LAGEGItCUeRCWeAx6x2Jmbav65nAwoPXfewtAdtbtit/pJFLUWOhpv0FpS6GQAmPrHA==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] - '@esbuild/linux-riscv64@0.25.12': - resolution: {integrity: sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==} + '@esbuild/linux-riscv64@0.27.4': + resolution: {integrity: sha512-BnASypppbUWyqjd1KIpU4AUBiIhVr6YlHx/cnPgqEkNoVOhHg+YiSVxM1RLfiy4t9cAulbRGTNCKOcqHrEQLIw==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] - '@esbuild/linux-s390x@0.25.12': - resolution: {integrity: sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==} + '@esbuild/linux-s390x@0.27.4': + resolution: {integrity: sha512-+eUqgb/Z7vxVLezG8bVB9SfBie89gMueS+I0xYh2tJdw3vqA/0ImZJ2ROeWwVJN59ihBeZ7Tu92dF/5dy5FttA==} engines: {node: '>=18'} cpu: [s390x] os: [linux] - '@esbuild/linux-x64@0.25.12': - resolution: {integrity: sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==} + '@esbuild/linux-x64@0.27.4': + resolution: {integrity: sha512-S5qOXrKV8BQEzJPVxAwnryi2+Iq5pB40gTEIT69BQONqR7JH1EPIcQ/Uiv9mCnn05jff9umq/5nqzxlqTOg9NA==} engines: {node: '>=18'} cpu: [x64] os: [linux] - '@esbuild/netbsd-arm64@0.25.12': - resolution: {integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==} + '@esbuild/netbsd-arm64@0.27.4': + resolution: {integrity: sha512-xHT8X4sb0GS8qTqiwzHqpY00C95DPAq7nAwX35Ie/s+LO9830hrMd3oX0ZMKLvy7vsonee73x0lmcdOVXFzd6Q==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] - '@esbuild/netbsd-x64@0.25.12': - resolution: {integrity: sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==} + '@esbuild/netbsd-x64@0.27.4': + resolution: {integrity: sha512-RugOvOdXfdyi5Tyv40kgQnI0byv66BFgAqjdgtAKqHoZTbTF2QqfQrFwa7cHEORJf6X2ht+l9ABLMP0dnKYsgg==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] - '@esbuild/openbsd-arm64@0.25.12': - resolution: {integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==} + '@esbuild/openbsd-arm64@0.27.4': + resolution: {integrity: sha512-2MyL3IAaTX+1/qP0O1SwskwcwCoOI4kV2IBX1xYnDDqthmq5ArrW94qSIKCAuRraMgPOmG0RDTA74mzYNQA9ow==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] - '@esbuild/openbsd-x64@0.25.12': - resolution: {integrity: sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==} + '@esbuild/openbsd-x64@0.27.4': + resolution: {integrity: sha512-u8fg/jQ5aQDfsnIV6+KwLOf1CmJnfu1ShpwqdwC0uA7ZPwFws55Ngc12vBdeUdnuWoQYx/SOQLGDcdlfXhYmXQ==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] - '@esbuild/openharmony-arm64@0.25.12': - resolution: {integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==} + '@esbuild/openharmony-arm64@0.27.4': + resolution: {integrity: sha512-JkTZrl6VbyO8lDQO3yv26nNr2RM2yZzNrNHEsj9bm6dOwwu9OYN28CjzZkH57bh4w0I2F7IodpQvUAEd1mbWXg==} engines: {node: '>=18'} cpu: [arm64] os: [openharmony] - '@esbuild/sunos-x64@0.25.12': - resolution: {integrity: sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==} + '@esbuild/sunos-x64@0.27.4': + resolution: {integrity: sha512-/gOzgaewZJfeJTlsWhvUEmUG4tWEY2Spp5M20INYRg2ZKl9QPO3QEEgPeRtLjEWSW8FilRNacPOg8R1uaYkA6g==} engines: {node: '>=18'} cpu: [x64] os: [sunos] - '@esbuild/win32-arm64@0.25.12': - resolution: {integrity: sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==} + '@esbuild/win32-arm64@0.27.4': + resolution: {integrity: sha512-Z9SExBg2y32smoDQdf1HRwHRt6vAHLXcxD2uGgO/v2jK7Y718Ix4ndsbNMU/+1Qiem9OiOdaqitioZwxivhXYg==} engines: {node: '>=18'} cpu: [arm64] os: [win32] - '@esbuild/win32-ia32@0.25.12': - resolution: {integrity: sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==} + '@esbuild/win32-ia32@0.27.4': + resolution: {integrity: sha512-DAyGLS0Jz5G5iixEbMHi5KdiApqHBWMGzTtMiJ72ZOLhbu/bzxgAe8Ue8CTS3n3HbIUHQz/L51yMdGMeoxXNJw==} engines: {node: '>=18'} cpu: [ia32] os: [win32] - '@esbuild/win32-x64@0.25.12': - resolution: {integrity: sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==} + '@esbuild/win32-x64@0.27.4': + resolution: {integrity: sha512-+knoa0BDoeXgkNvvV1vvbZX4+hizelrkwmGJBdT17t8FNPwG2lKemmuMZlmaNQ3ws3DKKCxpb4zRZEIp3UxFCg==} engines: {node: '>=18'} cpu: [x64] os: [win32] - '@iconify-json/simple-icons@1.2.61': - resolution: {integrity: sha512-DG6z3VEAxtDEw/SuZssZ/E8EvhjBhFQqxpEo3uckRKiia3LfZHmM4cx4RsaO2qX1Bqo9uadR5c/hYavvUQVuHw==} + '@iconify-json/simple-icons@1.2.74': + resolution: {integrity: sha512-yqaohfY6jnYjTVpuTkaBQHrWbdUrQyWXhau0r/0EZiNWYXPX/P8WWwl1DoLH5CbvDjjcWQw5J0zADhgCUklOqA==} '@iconify/types@2.0.0': resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} @@ -217,139 +220,167 @@ packages: '@jridgewell/sourcemap-codec@1.5.5': resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} - '@rolldown/pluginutils@1.0.0-beta.50': - resolution: {integrity: sha512-5e76wQiQVeL1ICOZVUg4LSOVYg9jyhGCin+icYozhsUzM+fHE7kddi1bdiE0jwVqTfkjba3jUFbEkoC9WkdvyA==} + '@rolldown/pluginutils@1.0.0-rc.2': + resolution: {integrity: sha512-izyXV/v+cHiRfozX62W9htOAvwMo4/bXKDrQ+vom1L1qRuexPock/7VZDAhnpHCLNejd3NJ6hiab+tO0D44Rgw==} - '@rollup/rollup-android-arm-eabi@4.53.3': - resolution: {integrity: sha512-mRSi+4cBjrRLoaal2PnqH82Wqyb+d3HsPUN/W+WslCXsZsyHa9ZeQQX/pQsZaVIWDkPcpV6jJ+3KLbTbgnwv8w==} + '@rollup/rollup-android-arm-eabi@4.59.0': + resolution: {integrity: sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.53.3': - resolution: {integrity: sha512-CbDGaMpdE9sh7sCmTrTUyllhrg65t6SwhjlMJsLr+J8YjFuPmCEjbBSx4Z/e4SmDyH3aB5hGaJUP2ltV/vcs4w==} + '@rollup/rollup-android-arm64@4.59.0': + resolution: {integrity: sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.53.3': - resolution: {integrity: sha512-Nr7SlQeqIBpOV6BHHGZgYBuSdanCXuw09hon14MGOLGmXAFYjx1wNvquVPmpZnl0tLjg25dEdr4IQ6GgyToCUA==} + '@rollup/rollup-darwin-arm64@4.59.0': + resolution: {integrity: sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.53.3': - resolution: {integrity: sha512-DZ8N4CSNfl965CmPktJ8oBnfYr3F8dTTNBQkRlffnUarJ2ohudQD17sZBa097J8xhQ26AwhHJ5mvUyQW8ddTsQ==} + '@rollup/rollup-darwin-x64@4.59.0': + resolution: {integrity: sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.53.3': - resolution: {integrity: sha512-yMTrCrK92aGyi7GuDNtGn2sNW+Gdb4vErx4t3Gv/Tr+1zRb8ax4z8GWVRfr3Jw8zJWvpGHNpss3vVlbF58DZ4w==} + '@rollup/rollup-freebsd-arm64@4.59.0': + resolution: {integrity: sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.53.3': - resolution: {integrity: sha512-lMfF8X7QhdQzseM6XaX0vbno2m3hlyZFhwcndRMw8fbAGUGL3WFMBdK0hbUBIUYcEcMhVLr1SIamDeuLBnXS+Q==} + '@rollup/rollup-freebsd-x64@4.59.0': + resolution: {integrity: sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.53.3': - resolution: {integrity: sha512-k9oD15soC/Ln6d2Wv/JOFPzZXIAIFLp6B+i14KhxAfnq76ajt0EhYc5YPeX6W1xJkAdItcVT+JhKl1QZh44/qw==} + '@rollup/rollup-linux-arm-gnueabihf@4.59.0': + resolution: {integrity: sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==} cpu: [arm] os: [linux] + libc: [glibc] - '@rollup/rollup-linux-arm-musleabihf@4.53.3': - resolution: {integrity: sha512-vTNlKq+N6CK/8UktsrFuc+/7NlEYVxgaEgRXVUVK258Z5ymho29skzW1sutgYjqNnquGwVUObAaxae8rZ6YMhg==} + '@rollup/rollup-linux-arm-musleabihf@4.59.0': + resolution: {integrity: sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==} cpu: [arm] os: [linux] + libc: [musl] - '@rollup/rollup-linux-arm64-gnu@4.53.3': - resolution: {integrity: sha512-RGrFLWgMhSxRs/EWJMIFM1O5Mzuz3Xy3/mnxJp/5cVhZ2XoCAxJnmNsEyeMJtpK+wu0FJFWz+QF4mjCA7AUQ3w==} + '@rollup/rollup-linux-arm64-gnu@4.59.0': + resolution: {integrity: sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==} cpu: [arm64] os: [linux] + libc: [glibc] - '@rollup/rollup-linux-arm64-musl@4.53.3': - resolution: {integrity: sha512-kASyvfBEWYPEwe0Qv4nfu6pNkITLTb32p4yTgzFCocHnJLAHs+9LjUu9ONIhvfT/5lv4YS5muBHyuV84epBo/A==} + '@rollup/rollup-linux-arm64-musl@4.59.0': + resolution: {integrity: sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==} cpu: [arm64] os: [linux] + libc: [musl] - '@rollup/rollup-linux-loong64-gnu@4.53.3': - resolution: {integrity: sha512-JiuKcp2teLJwQ7vkJ95EwESWkNRFJD7TQgYmCnrPtlu50b4XvT5MOmurWNrCj3IFdyjBQ5p9vnrX4JM6I8OE7g==} + '@rollup/rollup-linux-loong64-gnu@4.59.0': + resolution: {integrity: sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==} cpu: [loong64] os: [linux] + libc: [glibc] - '@rollup/rollup-linux-ppc64-gnu@4.53.3': - resolution: {integrity: sha512-EoGSa8nd6d3T7zLuqdojxC20oBfNT8nexBbB/rkxgKj5T5vhpAQKKnD+h3UkoMuTyXkP5jTjK/ccNRmQrPNDuw==} + '@rollup/rollup-linux-loong64-musl@4.59.0': + resolution: {integrity: sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==} + cpu: [loong64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-ppc64-gnu@4.59.0': + resolution: {integrity: sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==} cpu: [ppc64] os: [linux] + libc: [glibc] - '@rollup/rollup-linux-riscv64-gnu@4.53.3': - resolution: {integrity: sha512-4s+Wped2IHXHPnAEbIB0YWBv7SDohqxobiiPA1FIWZpX+w9o2i4LezzH/NkFUl8LRci/8udci6cLq+jJQlh+0g==} + '@rollup/rollup-linux-ppc64-musl@4.59.0': + resolution: {integrity: sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==} + cpu: [ppc64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-riscv64-gnu@4.59.0': + resolution: {integrity: sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==} cpu: [riscv64] os: [linux] + libc: [glibc] - '@rollup/rollup-linux-riscv64-musl@4.53.3': - resolution: {integrity: sha512-68k2g7+0vs2u9CxDt5ktXTngsxOQkSEV/xBbwlqYcUrAVh6P9EgMZvFsnHy4SEiUl46Xf0IObWVbMvPrr2gw8A==} + '@rollup/rollup-linux-riscv64-musl@4.59.0': + resolution: {integrity: sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==} cpu: [riscv64] os: [linux] + libc: [musl] - '@rollup/rollup-linux-s390x-gnu@4.53.3': - resolution: {integrity: sha512-VYsFMpULAz87ZW6BVYw3I6sWesGpsP9OPcyKe8ofdg9LHxSbRMd7zrVrr5xi/3kMZtpWL/wC+UIJWJYVX5uTKg==} + '@rollup/rollup-linux-s390x-gnu@4.59.0': + resolution: {integrity: sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==} cpu: [s390x] os: [linux] + libc: [glibc] - '@rollup/rollup-linux-x64-gnu@4.53.3': - resolution: {integrity: sha512-3EhFi1FU6YL8HTUJZ51imGJWEX//ajQPfqWLI3BQq4TlvHy4X0MOr5q3D2Zof/ka0d5FNdPwZXm3Yyib/UEd+w==} + '@rollup/rollup-linux-x64-gnu@4.59.0': + resolution: {integrity: sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==} cpu: [x64] os: [linux] + libc: [glibc] - '@rollup/rollup-linux-x64-musl@4.53.3': - resolution: {integrity: sha512-eoROhjcc6HbZCJr+tvVT8X4fW3/5g/WkGvvmwz/88sDtSJzO7r/blvoBDgISDiCjDRZmHpwud7h+6Q9JxFwq1Q==} + '@rollup/rollup-linux-x64-musl@4.59.0': + resolution: {integrity: sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==} cpu: [x64] os: [linux] + libc: [musl] - '@rollup/rollup-openharmony-arm64@4.53.3': - resolution: {integrity: sha512-OueLAWgrNSPGAdUdIjSWXw+u/02BRTcnfw9PN41D2vq/JSEPnJnVuBgw18VkN8wcd4fjUs+jFHVM4t9+kBSNLw==} + '@rollup/rollup-openbsd-x64@4.59.0': + resolution: {integrity: sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==} + cpu: [x64] + os: [openbsd] + + '@rollup/rollup-openharmony-arm64@4.59.0': + resolution: {integrity: sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==} cpu: [arm64] os: [openharmony] - '@rollup/rollup-win32-arm64-msvc@4.53.3': - resolution: {integrity: sha512-GOFuKpsxR/whszbF/bzydebLiXIHSgsEUp6M0JI8dWvi+fFa1TD6YQa4aSZHtpmh2/uAlj/Dy+nmby3TJ3pkTw==} + '@rollup/rollup-win32-arm64-msvc@4.59.0': + resolution: {integrity: sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.53.3': - resolution: {integrity: sha512-iah+THLcBJdpfZ1TstDFbKNznlzoxa8fmnFYK4V67HvmuNYkVdAywJSoteUszvBQ9/HqN2+9AZghbajMsFT+oA==} + '@rollup/rollup-win32-ia32-msvc@4.59.0': + resolution: {integrity: sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-gnu@4.53.3': - resolution: {integrity: sha512-J9QDiOIZlZLdcot5NXEepDkstocktoVjkaKUtqzgzpt2yWjGlbYiKyp05rWwk4nypbYUNoFAztEgixoLaSETkg==} + '@rollup/rollup-win32-x64-gnu@4.59.0': + resolution: {integrity: sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==} cpu: [x64] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.53.3': - resolution: {integrity: sha512-UhTd8u31dXadv0MopwGgNOBpUVROFKWVQgAg5N1ESyCz8AuBcMqm4AuTjrwgQKGDfoFuz02EuMRHQIw/frmYKQ==} + '@rollup/rollup-win32-x64-msvc@4.59.0': + resolution: {integrity: sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==} cpu: [x64] os: [win32] - '@shikijs/core@3.19.0': - resolution: {integrity: sha512-L7SrRibU7ZoYi1/TrZsJOFAnnHyLTE1SwHG1yNWjZIVCqjOEmCSuK2ZO9thnRbJG6TOkPp+Z963JmpCNw5nzvA==} + '@shikijs/core@3.23.0': + resolution: {integrity: sha512-NSWQz0riNb67xthdm5br6lAkvpDJRTgB36fxlo37ZzM2yq0PQFFzbd8psqC2XMPgCzo1fW6cVi18+ArJ44wqgA==} - '@shikijs/engine-javascript@3.19.0': - resolution: {integrity: sha512-ZfWJNm2VMhKkQIKT9qXbs76RRcT0SF/CAvEz0+RkpUDAoDaCx0uFdCGzSRiD9gSlhm6AHkjdieOBJMaO2eC1rQ==} + '@shikijs/engine-javascript@3.23.0': + resolution: {integrity: sha512-aHt9eiGFobmWR5uqJUViySI1bHMqrAgamWE1TYSUoftkAeCCAiGawPMwM+VCadylQtF4V3VNOZ5LmfItH5f3yA==} - '@shikijs/engine-oniguruma@3.19.0': - resolution: {integrity: sha512-1hRxtYIJfJSZeM5ivbUXv9hcJP3PWRo5prG/V2sWwiubUKTa+7P62d2qxCW8jiVFX4pgRHhnHNp+qeR7Xl+6kg==} + '@shikijs/engine-oniguruma@3.23.0': + resolution: {integrity: sha512-1nWINwKXxKKLqPibT5f4pAFLej9oZzQTsby8942OTlsJzOBZ0MWKiwzMsd+jhzu8YPCHAswGnnN1YtQfirL35g==} - '@shikijs/langs@3.19.0': - resolution: {integrity: sha512-dBMFzzg1QiXqCVQ5ONc0z2ebyoi5BKz+MtfByLm0o5/nbUu3Iz8uaTCa5uzGiscQKm7lVShfZHU1+OG3t5hgwg==} + '@shikijs/langs@3.23.0': + resolution: {integrity: sha512-2Ep4W3Re5aB1/62RSYQInK9mM3HsLeB91cHqznAJMuylqjzNVAVCMnNWRHFtcNHXsoNRayP9z1qj4Sq3nMqYXg==} - '@shikijs/themes@3.19.0': - resolution: {integrity: sha512-H36qw+oh91Y0s6OlFfdSuQ0Ld+5CgB/VE6gNPK+Hk4VRbVG/XQgkjnt4KzfnnoO6tZPtKJKHPjwebOCfjd6F8A==} + '@shikijs/themes@3.23.0': + resolution: {integrity: sha512-5qySYa1ZgAT18HR/ypENL9cUSGOeI2x+4IvYJu4JgVJdizn6kG4ia5Q1jDEOi7gTbN4RbuYtmHh0W3eccOrjMA==} - '@shikijs/transformers@3.19.0': - resolution: {integrity: sha512-e6vwrsyw+wx4OkcrDbL+FVCxwx8jgKiCoXzakVur++mIWVcgpzIi8vxf4/b4dVTYrV/nUx5RjinMf4tq8YV8Fw==} + '@shikijs/transformers@3.23.0': + resolution: {integrity: sha512-F9msZVxdF+krQNSdQ4V+Ja5QemeAoTQ2jxt7nJCwhDsdF1JWS3KxIQXA3lQbyKwS3J61oHRUSv4jYWv3CkaKTQ==} - '@shikijs/types@3.19.0': - resolution: {integrity: sha512-Z2hdeEQlzuntf/BZpFG8a+Fsw9UVXdML7w0o3TgSXV3yNESGon+bs9ITkQb3Ki7zxoXOOu5oJWqZ2uto06V9iQ==} + '@shikijs/types@3.23.0': + resolution: {integrity: sha512-3JZ5HXOZfYjsYSk0yPwBrkupyYSLpAE26Qc0HLghhZNGTZg/SKxXIIgoxOpmmeQP0RRSDJTk1/vPfw9tbw+jSQ==} '@shikijs/vscode-textmate@10.0.2': resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} @@ -381,64 +412,64 @@ packages: '@ungap/structured-clone@1.3.0': resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} - '@vitejs/plugin-vue@6.0.2': - resolution: {integrity: sha512-iHmwV3QcVGGvSC1BG5bZ4z6iwa1SOpAPWmnjOErd4Ske+lZua5K9TtAVdx0gMBClJ28DViCbSmZitjWZsWO3LA==} + '@vitejs/plugin-vue@6.0.5': + resolution: {integrity: sha512-bL3AxKuQySfk1iGcBsQnoRVexTPJq0Z/ixFVM8OhVJAP6ZXXXLtM7NFKWhLl30Kg7uTBqIaPXbh+nuQCuBDedg==} engines: {node: ^20.19.0 || >=22.12.0} peerDependencies: - vite: ^5.0.0 || ^6.0.0 || ^7.0.0 + vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 vue: ^3.2.25 - '@vue/compiler-core@3.5.25': - resolution: {integrity: sha512-vay5/oQJdsNHmliWoZfHPoVZZRmnSWhug0BYT34njkYTPqClh3DNWLkZNJBVSjsNMrg0CCrBfoKkjZQPM/QVUw==} + '@vue/compiler-core@3.5.30': + resolution: {integrity: sha512-s3DfdZkcu/qExZ+td75015ljzHc6vE+30cFMGRPROYjqkroYI5NV2X1yAMX9UeyBNWB9MxCfPcsjpLS11nzkkw==} - '@vue/compiler-dom@3.5.25': - resolution: {integrity: sha512-4We0OAcMZsKgYoGlMjzYvaoErltdFI2/25wqanuTu+S4gismOTRTBPi4IASOjxWdzIwrYSjnqONfKvuqkXzE2Q==} + '@vue/compiler-dom@3.5.30': + resolution: {integrity: sha512-eCFYESUEVYHhiMuK4SQTldO3RYxyMR/UQL4KdGD1Yrkfdx4m/HYuZ9jSfPdA+nWJY34VWndiYdW/wZXyiPEB9g==} - '@vue/compiler-sfc@3.5.25': - resolution: {integrity: sha512-PUgKp2rn8fFsI++lF2sO7gwO2d9Yj57Utr5yEsDf3GNaQcowCLKL7sf+LvVFvtJDXUp/03+dC6f2+LCv5aK1ag==} + '@vue/compiler-sfc@3.5.30': + resolution: {integrity: sha512-LqmFPDn89dtU9vI3wHJnwaV6GfTRD87AjWpTWpyrdVOObVtjIuSeZr181z5C4PmVx/V3j2p+0f7edFKGRMpQ5A==} - '@vue/compiler-ssr@3.5.25': - resolution: {integrity: sha512-ritPSKLBcParnsKYi+GNtbdbrIE1mtuFEJ4U1sWeuOMlIziK5GtOL85t5RhsNy4uWIXPgk+OUdpnXiTdzn8o3A==} + '@vue/compiler-ssr@3.5.30': + resolution: {integrity: sha512-NsYK6OMTnx109PSL2IAyf62JP6EUdk4Dmj6AkWcJGBvN0dQoMYtVekAmdqgTtWQgEJo+Okstbf/1p7qZr5H+bA==} - '@vue/devtools-api@8.0.5': - resolution: {integrity: sha512-DgVcW8H/Nral7LgZEecYFFYXnAvGuN9C3L3DtWekAncFBedBczpNW8iHKExfaM559Zm8wQWrwtYZ9lXthEHtDw==} + '@vue/devtools-api@8.1.0': + resolution: {integrity: sha512-O44X57jjkLKbLEc4OgL/6fEPOOanRJU8kYpCE8qfKlV96RQZcdzrcLI5mxMuVRUeXhHKIHGhCpHacyCk0HyO4w==} - '@vue/devtools-kit@8.0.5': - resolution: {integrity: sha512-q2VV6x1U3KJMTQPUlRMyWEKVbcHuxhqJdSr6Jtjz5uAThAIrfJ6WVZdGZm5cuO63ZnSUz0RCsVwiUUb0mDV0Yg==} + '@vue/devtools-kit@8.1.0': + resolution: {integrity: sha512-/NZlS4WtGIB54DA/z10gzk+n/V7zaqSzYZOVlg2CfdnpIKdB61bd7JDIMxf/zrtX41zod8E2/bbEBoW/d7x70Q==} - '@vue/devtools-shared@8.0.5': - resolution: {integrity: sha512-bRLn6/spxpmgLk+iwOrR29KrYnJjG9DGpHGkDFG82UM21ZpJ39ztUT9OXX3g+usW7/b2z+h46I9ZiYyB07XMXg==} + '@vue/devtools-shared@8.1.0': + resolution: {integrity: sha512-h8uCb4Qs8UT8VdTT5yjY6tOJ//qH7EpxToixR0xqejR55t5OdISIg7AJ7eBkhBs8iu1qG5gY3QQNN1DF1EelAA==} - '@vue/reactivity@3.5.25': - resolution: {integrity: sha512-5xfAypCQepv4Jog1U4zn8cZIcbKKFka3AgWHEFQeK65OW+Ys4XybP6z2kKgws4YB43KGpqp5D/K3go2UPPunLA==} + '@vue/reactivity@3.5.30': + resolution: {integrity: sha512-179YNgKATuwj9gB+66snskRDOitDiuOZqkYia7mHKJaidOMo/WJxHKF8DuGc4V4XbYTJANlfEKb0yxTQotnx4Q==} - '@vue/runtime-core@3.5.25': - resolution: {integrity: sha512-Z751v203YWwYzy460bzsYQISDfPjHTl+6Zzwo/a3CsAf+0ccEjQ8c+0CdX1WsumRTHeywvyUFtW6KvNukT/smA==} + '@vue/runtime-core@3.5.30': + resolution: {integrity: sha512-e0Z+8PQsUTdwV8TtEsLzUM7SzC7lQwYKePydb7K2ZnmS6jjND+WJXkmmfh/swYzRyfP1EY3fpdesyYoymCzYfg==} - '@vue/runtime-dom@3.5.25': - resolution: {integrity: sha512-a4WrkYFbb19i9pjkz38zJBg8wa/rboNERq3+hRRb0dHiJh13c+6kAbgqCPfMaJ2gg4weWD3APZswASOfmKwamA==} + '@vue/runtime-dom@3.5.30': + resolution: {integrity: sha512-2UIGakjU4WSQ0T4iwDEW0W7vQj6n7AFn7taqZ9Cvm0Q/RA2FFOziLESrDL4GmtI1wV3jXg5nMoJSYO66egDUBw==} - '@vue/server-renderer@3.5.25': - resolution: {integrity: sha512-UJaXR54vMG61i8XNIzTSf2Q7MOqZHpp8+x3XLGtE3+fL+nQd+k7O5+X3D/uWrnQXOdMw5VPih+Uremcw+u1woQ==} + '@vue/server-renderer@3.5.30': + resolution: {integrity: sha512-v+R34icapydRwbZRD0sXwtHqrQJv38JuMB4JxbOxd8NEpGLny7cncMp53W9UH/zo4j8eDHjQ1dEJXwzFQknjtQ==} peerDependencies: - vue: 3.5.25 + vue: 3.5.30 - '@vue/shared@3.5.25': - resolution: {integrity: sha512-AbOPdQQnAnzs58H2FrrDxYj/TJfmeS2jdfEEhgiKINy+bnOANmVizIEgq1r+C5zsbs6l1CCQxtcj71rwNQ4jWg==} + '@vue/shared@3.5.30': + resolution: {integrity: sha512-YXgQ7JjaO18NeK2K9VTbDHaFy62WrObMa6XERNfNOkAhD1F1oDSf3ZJ7K6GqabZ0BvSDHajp8qfS5Sa2I9n8uQ==} - '@vueuse/core@14.1.0': - resolution: {integrity: sha512-rgBinKs07hAYyPF834mDTigH7BtPqvZ3Pryuzt1SD/lg5wEcWqvwzXXYGEDb2/cP0Sj5zSvHl3WkmMELr5kfWw==} + '@vueuse/core@14.2.1': + resolution: {integrity: sha512-3vwDzV+GDUNpdegRY6kzpLm4Igptq+GA0QkJ3W61Iv27YWwW/ufSlOfgQIpN6FZRMG0mkaz4gglJRtq5SeJyIQ==} peerDependencies: vue: ^3.5.0 - '@vueuse/integrations@14.1.0': - resolution: {integrity: sha512-eNQPdisnO9SvdydTIXnTE7c29yOsJBD/xkwEyQLdhDC/LKbqrFpXHb3uS//7NcIrQO3fWVuvMGp8dbK6mNEMCA==} + '@vueuse/integrations@14.2.1': + resolution: {integrity: sha512-2LIUpBi/67PoXJGqSDQUF0pgQWpNHh7beiA+KG2AbybcNm+pTGWT6oPGlBgUoDWmYwfeQqM/uzOHqcILpKL7nA==} peerDependencies: async-validator: ^4 axios: ^1 change-case: ^5 drauu: ^0.4 - focus-trap: ^7 + focus-trap: ^7 || ^8 fuse.js: ^7 idb-keyval: ^6 jwt-decode: ^4 @@ -473,11 +504,11 @@ packages: universal-cookie: optional: true - '@vueuse/metadata@14.1.0': - resolution: {integrity: sha512-7hK4g015rWn2PhKcZ99NyT+ZD9sbwm7SGvp7k+k+rKGWnLjS/oQozoIZzWfCewSUeBmnJkIb+CNr7Zc/EyRnnA==} + '@vueuse/metadata@14.2.1': + resolution: {integrity: sha512-1ButlVtj5Sb/HDtIy1HFr1VqCP4G6Ypqt5MAo0lCgjokrk2mvQKsK2uuy0vqu/Ks+sHfuHo0B9Y9jn9xKdjZsw==} - '@vueuse/shared@14.1.0': - resolution: {integrity: sha512-EcKxtYvn6gx1F8z9J5/rsg3+lTQnvOruQd8fUecW99DCK04BkWD7z5KQ/wTAx+DazyoEE9dJt/zV8OIEQbM6kw==} + '@vueuse/shared@14.2.1': + resolution: {integrity: sha512-shTJncjV9JTI4oVNyF1FQonetYAiTBd+Qj7cY89SWbXSkx7gyhrgtEdF2ZAVWS1S3SHlaROO6F2IesJxQEkZBw==} peerDependencies: vue: ^3.5.0 @@ -522,10 +553,6 @@ packages: comma-separated-tokens@2.0.3: resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} - copy-anything@4.0.5: - resolution: {integrity: sha512-7Vv6asjS4gMOuILabD3l739tsaxFQmC+a7pLZm02zyvs8p977bL3zEgq3yDk5rn9B0PbYgIv++jmHcuUab4RhA==} - engines: {node: '>=18'} - cross-spawn@7.0.6: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} @@ -549,12 +576,12 @@ packages: emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - entities@4.5.0: - resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + entities@7.0.1: + resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==} engines: {node: '>=0.12'} - esbuild@0.25.12: - resolution: {integrity: sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==} + esbuild@0.27.4: + resolution: {integrity: sha512-Rq4vbHnYkK5fws5NF7MYTU68FPRE1ajX7heQ/8QXXWqNgqqJ/GkmmyxIzUnf2Sr/bakf8l54716CcMGHYhMrrQ==} engines: {node: '>=18'} hasBin: true @@ -579,8 +606,8 @@ packages: picomatch: optional: true - focus-trap@7.6.6: - resolution: {integrity: sha512-v/Z8bvMCajtx4mEXmOo7QEsIzlIOqRXTIwgUfsFOF9gEsespdbD0AkPIka1bSXZ8Y8oZ+2IVDQZePkTfEHZl7Q==} + focus-trap@7.8.0: + resolution: {integrity: sha512-/yNdlIkpWbM0ptxno3ONTuf+2g318kh2ez3KSeZN5dZ8YC6AAmgeWz+GasYYiBJPFaYcSAPeu4GfhUaChzIJXA==} foreground-child@3.3.1: resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} @@ -609,9 +636,6 @@ packages: hookable@5.5.3: resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==} - htm@3.1.1: - resolution: {integrity: sha512-983Vyg8NwUE7JkZ6NmOqpCZ+sh1bKv2iYTlUkzlWmA5JD2acKoxd4KVxbMmxX/85mtfdnDmTFoNKcg5DGAvxNQ==} - html-void-elements@3.0.0: resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} @@ -623,10 +647,6 @@ packages: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} - is-what@5.5.0: - resolution: {integrity: sha512-oG7cgbmg5kLYae2N5IVd3jm2s+vldjxJzK1pcu9LfpGuQ93MQSzo0okvRna+7y5ifrD+20FE8FvjusyGaz14fw==} - engines: {node: '>=18'} - isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} @@ -681,9 +701,6 @@ packages: minisearch@7.2.0: resolution: {integrity: sha512-dqT2XBYUOZOiC5t2HRnwADjhNS2cecp9u+TJRiJ1Qp/f5qjkeT5APcGPjHw+bz89Ms8Jp+cG4AlE+QZ/QnDglg==} - mitt@3.0.1: - resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} - nanoid@3.3.11: resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} @@ -692,8 +709,8 @@ packages: oniguruma-parser@0.12.1: resolution: {integrity: sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w==} - oniguruma-to-es@4.3.4: - resolution: {integrity: sha512-3VhUGN3w2eYxnTzHn+ikMI+fp/96KoRSVK9/kMTcFqj1NRDh2IhQCKvYxDnWePKRXY/AqH+Fuiyb7VHSzBjHfA==} + oniguruma-to-es@4.3.5: + resolution: {integrity: sha512-Zjygswjpsewa0NLTsiizVuMQZbp0MDyM6lIt66OxsF21npUDlzpHi1Mgb/qhQdkb+dWFTzJmFbEWdvZgRho8eQ==} package-json-from-dist@1.0.1: resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} @@ -706,8 +723,8 @@ packages: resolution: {integrity: sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==} engines: {node: 20 || >=22} - perfect-debounce@2.0.0: - resolution: {integrity: sha512-fkEH/OBiKrqqI/yIgjR92lMfs2K8105zt/VT6+7eTjNwisrsh47CeIED9z58zI7DfKdH3uHAn25ziRZn3kgAow==} + perfect-debounce@2.1.0: + resolution: {integrity: sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g==} picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -716,8 +733,8 @@ packages: resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} engines: {node: '>=12'} - postcss@8.5.6: - resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} + postcss@8.5.8: + resolution: {integrity: sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==} engines: {node: ^10 || ^12 || >=14} property-information@7.1.0: @@ -733,14 +750,11 @@ packages: regex-utilities@2.3.0: resolution: {integrity: sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==} - regex@6.0.1: - resolution: {integrity: sha512-uorlqlzAKjKQZ5P+kTJr3eeJGSVroLKoHmquUj4zHWuR+hEyNqlXsSKlYYF5F4NI6nl7tWCs0apKJ0lmfsXAPA==} + regex@6.1.0: + resolution: {integrity: sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==} - rfdc@1.4.1: - resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} - - rollup@4.53.3: - resolution: {integrity: sha512-w8GmOxZfBmKknvdXU1sdM9NHcoQejwF/4mNgj2JuEEdRaHwwF12K7e9eXn1nLZ07ad+du76mkVsyeb2rKGllsA==} + rollup@4.59.0: + resolution: {integrity: sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -756,8 +770,8 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} - shiki@3.19.0: - resolution: {integrity: sha512-77VJr3OR/VUZzPiStyRhADmO2jApMM0V2b1qf0RpfWya8Zr1PeZev5AEpPGAAKWdiYUtcZGBE4F5QvJml1PvWA==} + shiki@3.23.0: + resolution: {integrity: sha512-55Dj73uq9ZXL5zyeRPzHQsK7Nbyt6Y10k5s7OjuFZGMhpp4r/rsLBH0o/0fstIzX1Lep9VxefWljK/SKCzygIA==} signal-exit@4.1.0: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} @@ -770,10 +784,6 @@ packages: space-separated-tokens@2.0.2: resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} - speakingurl@14.0.1: - resolution: {integrity: sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==} - engines: {node: '>=0.10.0'} - sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} @@ -800,12 +810,8 @@ packages: resolution: {integrity: sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==} engines: {node: '>=0.10.0'} - superjson@2.2.6: - resolution: {integrity: sha512-H+ue8Zo4vJmV2nRjpx86P35lzwDT3nItnIsocgumgr0hHMQ+ZGq5vrERg9kJBo5AWGmxZDhzDo+WVIJqkB0cGA==} - engines: {node: '>=16'} - - tabbable@6.3.0: - resolution: {integrity: sha512-EIHvdY5bPLuWForiR/AN2Bxngzpuwn1is4asboytXtpTgsArc+WmSJKVLlhdh71u7jFcryDqB2A8lQvj78MkyQ==} + tabbable@6.4.0: + resolution: {integrity: sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg==} tinyglobby@0.2.15: resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} @@ -826,8 +832,8 @@ packages: unist-util-visit-parents@6.0.2: resolution: {integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==} - unist-util-visit@5.0.0: - resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==} + unist-util-visit@5.1.0: + resolution: {integrity: sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==} vfile-message@4.0.3: resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} @@ -835,8 +841,8 @@ packages: vfile@6.0.3: resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} - vite@7.2.6: - resolution: {integrity: sha512-tI2l/nFHC5rLh7+5+o7QjKjSR04ivXDF4jcgV0f/bTQ+OJiITy5S6gaynVsEM+7RqzufMnVbIon6Sr5x1SDYaQ==} + vite@7.3.1: + resolution: {integrity: sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: @@ -879,8 +885,8 @@ packages: resolution: {integrity: sha512-wPUbXezGakVldawixeRW5tKQTLKoMj2t4nWoThKfCltBM/9a38IE+wCXmmRNW22ZKC32SD/X/sG6NyCTK8QBRg==} engines: {node: '>=18.0.0'} - vitepress@2.0.0-alpha.15: - resolution: {integrity: sha512-jhjSYd10Z6RZiKOa7jy0xMVf5NB5oSc/lS3bD/QoUc6V8PrvQR5JhC9104NEt6+oTGY/ftieVWxY9v7YI+1IjA==} + vitepress@2.0.0-alpha.16: + resolution: {integrity: sha512-w1nwsefDVIsje7BZr2tsKxkZutDGjG0YoQ2yxO7+a9tvYVqfljYbwj5LMYkPy8Tb7YbPwa22HtIhk62jbrvuEQ==} hasBin: true peerDependencies: markdown-it-mathjax3: ^4 @@ -894,8 +900,8 @@ packages: postcss: optional: true - vue@3.5.25: - resolution: {integrity: sha512-YLVdgv2K13WJ6n+kD5owehKtEXwdwXuj2TTyJMsO7pSeKw2bfRNZGjhB7YzrpbMYj5b5QsUebHpOqR3R3ziy/g==} + vue@3.5.30: + resolution: {integrity: sha512-hTHLc6VNZyzzEH/l7PFGjpcTvUgiaPK5mdLkbjrTeWSRcEfxFrv56g/XckIYlE9ckuobsdwqd5mk2g1sBkMewg==} peerDependencies: typescript: '*' peerDependenciesMeta: @@ -924,100 +930,100 @@ snapshots: '@babel/helper-validator-identifier@7.28.5': {} - '@babel/parser@7.28.5': + '@babel/parser@7.29.0': dependencies: - '@babel/types': 7.28.5 + '@babel/types': 7.29.0 - '@babel/types@7.28.5': + '@babel/types@7.29.0': dependencies: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.28.5 - '@docsearch/css@4.3.2': {} + '@docsearch/css@4.6.0': {} - '@docsearch/js@4.3.2': - dependencies: - htm: 3.1.1 + '@docsearch/js@4.6.0': {} - '@esbuild/aix-ppc64@0.25.12': + '@docsearch/sidepanel-js@4.6.0': {} + + '@esbuild/aix-ppc64@0.27.4': optional: true - '@esbuild/android-arm64@0.25.12': + '@esbuild/android-arm64@0.27.4': optional: true - '@esbuild/android-arm@0.25.12': + '@esbuild/android-arm@0.27.4': optional: true - '@esbuild/android-x64@0.25.12': + '@esbuild/android-x64@0.27.4': optional: true - '@esbuild/darwin-arm64@0.25.12': + '@esbuild/darwin-arm64@0.27.4': optional: true - '@esbuild/darwin-x64@0.25.12': + '@esbuild/darwin-x64@0.27.4': optional: true - '@esbuild/freebsd-arm64@0.25.12': + '@esbuild/freebsd-arm64@0.27.4': optional: true - '@esbuild/freebsd-x64@0.25.12': + '@esbuild/freebsd-x64@0.27.4': optional: true - '@esbuild/linux-arm64@0.25.12': + '@esbuild/linux-arm64@0.27.4': optional: true - '@esbuild/linux-arm@0.25.12': + '@esbuild/linux-arm@0.27.4': optional: true - '@esbuild/linux-ia32@0.25.12': + '@esbuild/linux-ia32@0.27.4': optional: true - '@esbuild/linux-loong64@0.25.12': + '@esbuild/linux-loong64@0.27.4': optional: true - '@esbuild/linux-mips64el@0.25.12': + '@esbuild/linux-mips64el@0.27.4': optional: true - '@esbuild/linux-ppc64@0.25.12': + '@esbuild/linux-ppc64@0.27.4': optional: true - '@esbuild/linux-riscv64@0.25.12': + '@esbuild/linux-riscv64@0.27.4': optional: true - '@esbuild/linux-s390x@0.25.12': + '@esbuild/linux-s390x@0.27.4': optional: true - '@esbuild/linux-x64@0.25.12': + '@esbuild/linux-x64@0.27.4': optional: true - '@esbuild/netbsd-arm64@0.25.12': + '@esbuild/netbsd-arm64@0.27.4': optional: true - '@esbuild/netbsd-x64@0.25.12': + '@esbuild/netbsd-x64@0.27.4': optional: true - '@esbuild/openbsd-arm64@0.25.12': + '@esbuild/openbsd-arm64@0.27.4': optional: true - '@esbuild/openbsd-x64@0.25.12': + '@esbuild/openbsd-x64@0.27.4': optional: true - '@esbuild/openharmony-arm64@0.25.12': + '@esbuild/openharmony-arm64@0.27.4': optional: true - '@esbuild/sunos-x64@0.25.12': + '@esbuild/sunos-x64@0.27.4': optional: true - '@esbuild/win32-arm64@0.25.12': + '@esbuild/win32-arm64@0.27.4': optional: true - '@esbuild/win32-ia32@0.25.12': + '@esbuild/win32-ia32@0.27.4': optional: true - '@esbuild/win32-x64@0.25.12': + '@esbuild/win32-x64@0.27.4': optional: true - '@iconify-json/simple-icons@1.2.61': + '@iconify-json/simple-icons@1.2.74': dependencies: '@iconify/types': 2.0.0 @@ -1040,106 +1046,115 @@ snapshots: '@jridgewell/sourcemap-codec@1.5.5': {} - '@rolldown/pluginutils@1.0.0-beta.50': {} + '@rolldown/pluginutils@1.0.0-rc.2': {} - '@rollup/rollup-android-arm-eabi@4.53.3': + '@rollup/rollup-android-arm-eabi@4.59.0': optional: true - '@rollup/rollup-android-arm64@4.53.3': + '@rollup/rollup-android-arm64@4.59.0': optional: true - '@rollup/rollup-darwin-arm64@4.53.3': + '@rollup/rollup-darwin-arm64@4.59.0': optional: true - '@rollup/rollup-darwin-x64@4.53.3': + '@rollup/rollup-darwin-x64@4.59.0': optional: true - '@rollup/rollup-freebsd-arm64@4.53.3': + '@rollup/rollup-freebsd-arm64@4.59.0': optional: true - '@rollup/rollup-freebsd-x64@4.53.3': + '@rollup/rollup-freebsd-x64@4.59.0': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.53.3': + '@rollup/rollup-linux-arm-gnueabihf@4.59.0': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.53.3': + '@rollup/rollup-linux-arm-musleabihf@4.59.0': optional: true - '@rollup/rollup-linux-arm64-gnu@4.53.3': + '@rollup/rollup-linux-arm64-gnu@4.59.0': optional: true - '@rollup/rollup-linux-arm64-musl@4.53.3': + '@rollup/rollup-linux-arm64-musl@4.59.0': optional: true - '@rollup/rollup-linux-loong64-gnu@4.53.3': + '@rollup/rollup-linux-loong64-gnu@4.59.0': optional: true - '@rollup/rollup-linux-ppc64-gnu@4.53.3': + '@rollup/rollup-linux-loong64-musl@4.59.0': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.53.3': + '@rollup/rollup-linux-ppc64-gnu@4.59.0': optional: true - '@rollup/rollup-linux-riscv64-musl@4.53.3': + '@rollup/rollup-linux-ppc64-musl@4.59.0': optional: true - '@rollup/rollup-linux-s390x-gnu@4.53.3': + '@rollup/rollup-linux-riscv64-gnu@4.59.0': optional: true - '@rollup/rollup-linux-x64-gnu@4.53.3': + '@rollup/rollup-linux-riscv64-musl@4.59.0': optional: true - '@rollup/rollup-linux-x64-musl@4.53.3': + '@rollup/rollup-linux-s390x-gnu@4.59.0': optional: true - '@rollup/rollup-openharmony-arm64@4.53.3': + '@rollup/rollup-linux-x64-gnu@4.59.0': optional: true - '@rollup/rollup-win32-arm64-msvc@4.53.3': + '@rollup/rollup-linux-x64-musl@4.59.0': optional: true - '@rollup/rollup-win32-ia32-msvc@4.53.3': + '@rollup/rollup-openbsd-x64@4.59.0': optional: true - '@rollup/rollup-win32-x64-gnu@4.53.3': + '@rollup/rollup-openharmony-arm64@4.59.0': optional: true - '@rollup/rollup-win32-x64-msvc@4.53.3': + '@rollup/rollup-win32-arm64-msvc@4.59.0': optional: true - '@shikijs/core@3.19.0': + '@rollup/rollup-win32-ia32-msvc@4.59.0': + optional: true + + '@rollup/rollup-win32-x64-gnu@4.59.0': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.59.0': + optional: true + + '@shikijs/core@3.23.0': dependencies: - '@shikijs/types': 3.19.0 + '@shikijs/types': 3.23.0 '@shikijs/vscode-textmate': 10.0.2 '@types/hast': 3.0.4 hast-util-to-html: 9.0.5 - '@shikijs/engine-javascript@3.19.0': + '@shikijs/engine-javascript@3.23.0': dependencies: - '@shikijs/types': 3.19.0 + '@shikijs/types': 3.23.0 '@shikijs/vscode-textmate': 10.0.2 - oniguruma-to-es: 4.3.4 + oniguruma-to-es: 4.3.5 - '@shikijs/engine-oniguruma@3.19.0': + '@shikijs/engine-oniguruma@3.23.0': dependencies: - '@shikijs/types': 3.19.0 + '@shikijs/types': 3.23.0 '@shikijs/vscode-textmate': 10.0.2 - '@shikijs/langs@3.19.0': + '@shikijs/langs@3.23.0': dependencies: - '@shikijs/types': 3.19.0 + '@shikijs/types': 3.23.0 - '@shikijs/themes@3.19.0': + '@shikijs/themes@3.23.0': dependencies: - '@shikijs/types': 3.19.0 + '@shikijs/types': 3.23.0 - '@shikijs/transformers@3.19.0': + '@shikijs/transformers@3.23.0': dependencies: - '@shikijs/core': 3.19.0 - '@shikijs/types': 3.19.0 + '@shikijs/core': 3.23.0 + '@shikijs/types': 3.23.0 - '@shikijs/types@3.19.0': + '@shikijs/types@3.23.0': dependencies: '@shikijs/vscode-textmate': 10.0.2 '@types/hast': 3.0.4 @@ -1171,104 +1186,99 @@ snapshots: '@ungap/structured-clone@1.3.0': {} - '@vitejs/plugin-vue@6.0.2(vite@7.2.6)(vue@3.5.25)': + '@vitejs/plugin-vue@6.0.5(vite@7.3.1)(vue@3.5.30)': dependencies: - '@rolldown/pluginutils': 1.0.0-beta.50 - vite: 7.2.6 - vue: 3.5.25 + '@rolldown/pluginutils': 1.0.0-rc.2 + vite: 7.3.1 + vue: 3.5.30 - '@vue/compiler-core@3.5.25': + '@vue/compiler-core@3.5.30': dependencies: - '@babel/parser': 7.28.5 - '@vue/shared': 3.5.25 - entities: 4.5.0 + '@babel/parser': 7.29.0 + '@vue/shared': 3.5.30 + entities: 7.0.1 estree-walker: 2.0.2 source-map-js: 1.2.1 - '@vue/compiler-dom@3.5.25': + '@vue/compiler-dom@3.5.30': dependencies: - '@vue/compiler-core': 3.5.25 - '@vue/shared': 3.5.25 + '@vue/compiler-core': 3.5.30 + '@vue/shared': 3.5.30 - '@vue/compiler-sfc@3.5.25': + '@vue/compiler-sfc@3.5.30': dependencies: - '@babel/parser': 7.28.5 - '@vue/compiler-core': 3.5.25 - '@vue/compiler-dom': 3.5.25 - '@vue/compiler-ssr': 3.5.25 - '@vue/shared': 3.5.25 + '@babel/parser': 7.29.0 + '@vue/compiler-core': 3.5.30 + '@vue/compiler-dom': 3.5.30 + '@vue/compiler-ssr': 3.5.30 + '@vue/shared': 3.5.30 estree-walker: 2.0.2 magic-string: 0.30.21 - postcss: 8.5.6 + postcss: 8.5.8 source-map-js: 1.2.1 - '@vue/compiler-ssr@3.5.25': + '@vue/compiler-ssr@3.5.30': dependencies: - '@vue/compiler-dom': 3.5.25 - '@vue/shared': 3.5.25 + '@vue/compiler-dom': 3.5.30 + '@vue/shared': 3.5.30 - '@vue/devtools-api@8.0.5': + '@vue/devtools-api@8.1.0': dependencies: - '@vue/devtools-kit': 8.0.5 + '@vue/devtools-kit': 8.1.0 - '@vue/devtools-kit@8.0.5': + '@vue/devtools-kit@8.1.0': dependencies: - '@vue/devtools-shared': 8.0.5 + '@vue/devtools-shared': 8.1.0 birpc: 2.9.0 hookable: 5.5.3 - mitt: 3.0.1 - perfect-debounce: 2.0.0 - speakingurl: 14.0.1 - superjson: 2.2.6 + perfect-debounce: 2.1.0 - '@vue/devtools-shared@8.0.5': - dependencies: - rfdc: 1.4.1 + '@vue/devtools-shared@8.1.0': {} - '@vue/reactivity@3.5.25': + '@vue/reactivity@3.5.30': dependencies: - '@vue/shared': 3.5.25 + '@vue/shared': 3.5.30 - '@vue/runtime-core@3.5.25': + '@vue/runtime-core@3.5.30': dependencies: - '@vue/reactivity': 3.5.25 - '@vue/shared': 3.5.25 + '@vue/reactivity': 3.5.30 + '@vue/shared': 3.5.30 - '@vue/runtime-dom@3.5.25': + '@vue/runtime-dom@3.5.30': dependencies: - '@vue/reactivity': 3.5.25 - '@vue/runtime-core': 3.5.25 - '@vue/shared': 3.5.25 + '@vue/reactivity': 3.5.30 + '@vue/runtime-core': 3.5.30 + '@vue/shared': 3.5.30 csstype: 3.2.3 - '@vue/server-renderer@3.5.25(vue@3.5.25)': + '@vue/server-renderer@3.5.30(vue@3.5.30)': dependencies: - '@vue/compiler-ssr': 3.5.25 - '@vue/shared': 3.5.25 - vue: 3.5.25 + '@vue/compiler-ssr': 3.5.30 + '@vue/shared': 3.5.30 + vue: 3.5.30 - '@vue/shared@3.5.25': {} + '@vue/shared@3.5.30': {} - '@vueuse/core@14.1.0(vue@3.5.25)': + '@vueuse/core@14.2.1(vue@3.5.30)': dependencies: '@types/web-bluetooth': 0.0.21 - '@vueuse/metadata': 14.1.0 - '@vueuse/shared': 14.1.0(vue@3.5.25) - vue: 3.5.25 + '@vueuse/metadata': 14.2.1 + '@vueuse/shared': 14.2.1(vue@3.5.30) + vue: 3.5.30 - '@vueuse/integrations@14.1.0(focus-trap@7.6.6)(vue@3.5.25)': + '@vueuse/integrations@14.2.1(focus-trap@7.8.0)(vue@3.5.30)': dependencies: - '@vueuse/core': 14.1.0(vue@3.5.25) - '@vueuse/shared': 14.1.0(vue@3.5.25) - vue: 3.5.25 + '@vueuse/core': 14.2.1(vue@3.5.30) + '@vueuse/shared': 14.2.1(vue@3.5.30) + vue: 3.5.30 optionalDependencies: - focus-trap: 7.6.6 + focus-trap: 7.8.0 - '@vueuse/metadata@14.1.0': {} + '@vueuse/metadata@14.2.1': {} - '@vueuse/shared@14.1.0(vue@3.5.25)': + '@vueuse/shared@14.2.1(vue@3.5.30)': dependencies: - vue: 3.5.25 + vue: 3.5.30 ansi-regex@5.0.1: {} @@ -1300,10 +1310,6 @@ snapshots: comma-separated-tokens@2.0.3: {} - copy-anything@4.0.5: - dependencies: - is-what: 5.5.0 - cross-spawn@7.0.6: dependencies: path-key: 3.1.1 @@ -1324,36 +1330,36 @@ snapshots: emoji-regex@9.2.2: {} - entities@4.5.0: {} + entities@7.0.1: {} - esbuild@0.25.12: + esbuild@0.27.4: optionalDependencies: - '@esbuild/aix-ppc64': 0.25.12 - '@esbuild/android-arm': 0.25.12 - '@esbuild/android-arm64': 0.25.12 - '@esbuild/android-x64': 0.25.12 - '@esbuild/darwin-arm64': 0.25.12 - '@esbuild/darwin-x64': 0.25.12 - '@esbuild/freebsd-arm64': 0.25.12 - '@esbuild/freebsd-x64': 0.25.12 - '@esbuild/linux-arm': 0.25.12 - '@esbuild/linux-arm64': 0.25.12 - '@esbuild/linux-ia32': 0.25.12 - '@esbuild/linux-loong64': 0.25.12 - '@esbuild/linux-mips64el': 0.25.12 - '@esbuild/linux-ppc64': 0.25.12 - '@esbuild/linux-riscv64': 0.25.12 - '@esbuild/linux-s390x': 0.25.12 - '@esbuild/linux-x64': 0.25.12 - '@esbuild/netbsd-arm64': 0.25.12 - '@esbuild/netbsd-x64': 0.25.12 - '@esbuild/openbsd-arm64': 0.25.12 - '@esbuild/openbsd-x64': 0.25.12 - '@esbuild/openharmony-arm64': 0.25.12 - '@esbuild/sunos-x64': 0.25.12 - '@esbuild/win32-arm64': 0.25.12 - '@esbuild/win32-ia32': 0.25.12 - '@esbuild/win32-x64': 0.25.12 + '@esbuild/aix-ppc64': 0.27.4 + '@esbuild/android-arm': 0.27.4 + '@esbuild/android-arm64': 0.27.4 + '@esbuild/android-x64': 0.27.4 + '@esbuild/darwin-arm64': 0.27.4 + '@esbuild/darwin-x64': 0.27.4 + '@esbuild/freebsd-arm64': 0.27.4 + '@esbuild/freebsd-x64': 0.27.4 + '@esbuild/linux-arm': 0.27.4 + '@esbuild/linux-arm64': 0.27.4 + '@esbuild/linux-ia32': 0.27.4 + '@esbuild/linux-loong64': 0.27.4 + '@esbuild/linux-mips64el': 0.27.4 + '@esbuild/linux-ppc64': 0.27.4 + '@esbuild/linux-riscv64': 0.27.4 + '@esbuild/linux-s390x': 0.27.4 + '@esbuild/linux-x64': 0.27.4 + '@esbuild/netbsd-arm64': 0.27.4 + '@esbuild/netbsd-x64': 0.27.4 + '@esbuild/openbsd-arm64': 0.27.4 + '@esbuild/openbsd-x64': 0.27.4 + '@esbuild/openharmony-arm64': 0.27.4 + '@esbuild/sunos-x64': 0.27.4 + '@esbuild/win32-arm64': 0.27.4 + '@esbuild/win32-ia32': 0.27.4 + '@esbuild/win32-x64': 0.27.4 esprima@4.0.1: {} @@ -1367,9 +1373,9 @@ snapshots: optionalDependencies: picomatch: 4.0.3 - focus-trap@7.6.6: + focus-trap@7.8.0: dependencies: - tabbable: 6.3.0 + tabbable: 6.4.0 foreground-child@3.3.1: dependencies: @@ -1415,16 +1421,12 @@ snapshots: hookable@5.5.3: {} - htm@3.1.1: {} - html-void-elements@3.0.0: {} is-extendable@0.1.1: {} is-fullwidth-code-point@3.0.0: {} - is-what@5.5.0: {} - isexe@2.0.0: {} jackspeak@4.1.1: @@ -1455,7 +1457,7 @@ snapshots: micromark-util-sanitize-uri: 2.0.1 trim-lines: 3.0.1 unist-util-position: 5.0.0 - unist-util-visit: 5.0.0 + unist-util-visit: 5.1.0 vfile: 6.0.3 micromark-util-character@2.1.1: @@ -1483,16 +1485,14 @@ snapshots: minisearch@7.2.0: {} - mitt@3.0.1: {} - nanoid@3.3.11: {} oniguruma-parser@0.12.1: {} - oniguruma-to-es@4.3.4: + oniguruma-to-es@4.3.5: dependencies: oniguruma-parser: 0.12.1 - regex: 6.0.1 + regex: 6.1.0 regex-recursion: 6.0.2 package-json-from-dist@1.0.1: {} @@ -1504,13 +1504,13 @@ snapshots: lru-cache: 11.2.4 minipass: 7.1.2 - perfect-debounce@2.0.0: {} + perfect-debounce@2.1.0: {} picocolors@1.1.1: {} picomatch@4.0.3: {} - postcss@8.5.6: + postcss@8.5.8: dependencies: nanoid: 3.3.11 picocolors: 1.1.1 @@ -1526,38 +1526,39 @@ snapshots: regex-utilities@2.3.0: {} - regex@6.0.1: + regex@6.1.0: dependencies: regex-utilities: 2.3.0 - rfdc@1.4.1: {} - - rollup@4.53.3: + rollup@4.59.0: dependencies: '@types/estree': 1.0.8 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.53.3 - '@rollup/rollup-android-arm64': 4.53.3 - '@rollup/rollup-darwin-arm64': 4.53.3 - '@rollup/rollup-darwin-x64': 4.53.3 - '@rollup/rollup-freebsd-arm64': 4.53.3 - '@rollup/rollup-freebsd-x64': 4.53.3 - '@rollup/rollup-linux-arm-gnueabihf': 4.53.3 - '@rollup/rollup-linux-arm-musleabihf': 4.53.3 - '@rollup/rollup-linux-arm64-gnu': 4.53.3 - '@rollup/rollup-linux-arm64-musl': 4.53.3 - '@rollup/rollup-linux-loong64-gnu': 4.53.3 - '@rollup/rollup-linux-ppc64-gnu': 4.53.3 - '@rollup/rollup-linux-riscv64-gnu': 4.53.3 - '@rollup/rollup-linux-riscv64-musl': 4.53.3 - '@rollup/rollup-linux-s390x-gnu': 4.53.3 - '@rollup/rollup-linux-x64-gnu': 4.53.3 - '@rollup/rollup-linux-x64-musl': 4.53.3 - '@rollup/rollup-openharmony-arm64': 4.53.3 - '@rollup/rollup-win32-arm64-msvc': 4.53.3 - '@rollup/rollup-win32-ia32-msvc': 4.53.3 - '@rollup/rollup-win32-x64-gnu': 4.53.3 - '@rollup/rollup-win32-x64-msvc': 4.53.3 + '@rollup/rollup-android-arm-eabi': 4.59.0 + '@rollup/rollup-android-arm64': 4.59.0 + '@rollup/rollup-darwin-arm64': 4.59.0 + '@rollup/rollup-darwin-x64': 4.59.0 + '@rollup/rollup-freebsd-arm64': 4.59.0 + '@rollup/rollup-freebsd-x64': 4.59.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.59.0 + '@rollup/rollup-linux-arm-musleabihf': 4.59.0 + '@rollup/rollup-linux-arm64-gnu': 4.59.0 + '@rollup/rollup-linux-arm64-musl': 4.59.0 + '@rollup/rollup-linux-loong64-gnu': 4.59.0 + '@rollup/rollup-linux-loong64-musl': 4.59.0 + '@rollup/rollup-linux-ppc64-gnu': 4.59.0 + '@rollup/rollup-linux-ppc64-musl': 4.59.0 + '@rollup/rollup-linux-riscv64-gnu': 4.59.0 + '@rollup/rollup-linux-riscv64-musl': 4.59.0 + '@rollup/rollup-linux-s390x-gnu': 4.59.0 + '@rollup/rollup-linux-x64-gnu': 4.59.0 + '@rollup/rollup-linux-x64-musl': 4.59.0 + '@rollup/rollup-openbsd-x64': 4.59.0 + '@rollup/rollup-openharmony-arm64': 4.59.0 + '@rollup/rollup-win32-arm64-msvc': 4.59.0 + '@rollup/rollup-win32-ia32-msvc': 4.59.0 + '@rollup/rollup-win32-x64-gnu': 4.59.0 + '@rollup/rollup-win32-x64-msvc': 4.59.0 fsevents: 2.3.3 section-matter@1.0.0: @@ -1571,14 +1572,14 @@ snapshots: shebang-regex@3.0.0: {} - shiki@3.19.0: + shiki@3.23.0: dependencies: - '@shikijs/core': 3.19.0 - '@shikijs/engine-javascript': 3.19.0 - '@shikijs/engine-oniguruma': 3.19.0 - '@shikijs/langs': 3.19.0 - '@shikijs/themes': 3.19.0 - '@shikijs/types': 3.19.0 + '@shikijs/core': 3.23.0 + '@shikijs/engine-javascript': 3.23.0 + '@shikijs/engine-oniguruma': 3.23.0 + '@shikijs/langs': 3.23.0 + '@shikijs/themes': 3.23.0 + '@shikijs/types': 3.23.0 '@shikijs/vscode-textmate': 10.0.2 '@types/hast': 3.0.4 @@ -1588,8 +1589,6 @@ snapshots: space-separated-tokens@2.0.2: {} - speakingurl@14.0.1: {} - sprintf-js@1.0.3: {} string-width@4.2.3: @@ -1619,11 +1618,7 @@ snapshots: strip-bom-string@1.0.0: {} - superjson@2.2.6: - dependencies: - copy-anything: 4.0.5 - - tabbable@6.3.0: {} + tabbable@6.4.0: {} tinyglobby@0.2.15: dependencies: @@ -1649,7 +1644,7 @@ snapshots: '@types/unist': 3.0.3 unist-util-is: 6.0.1 - unist-util-visit@5.0.0: + unist-util-visit@5.1.0: dependencies: '@types/unist': 3.0.3 unist-util-is: 6.0.1 @@ -1665,13 +1660,13 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.3 - vite@7.2.6: + vite@7.3.1: dependencies: - esbuild: 0.25.12 + esbuild: 0.27.4 fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 - postcss: 8.5.6 - rollup: 4.53.3 + postcss: 8.5.8 + rollup: 4.59.0 tinyglobby: 0.2.15 optionalDependencies: fsevents: 2.3.3 @@ -1682,28 +1677,29 @@ snapshots: gray-matter: 4.0.3 qsu: 1.10.4 - vitepress@2.0.0-alpha.15(postcss@8.5.6): + vitepress@2.0.0-alpha.16(postcss@8.5.8): dependencies: - '@docsearch/css': 4.3.2 - '@docsearch/js': 4.3.2 - '@iconify-json/simple-icons': 1.2.61 - '@shikijs/core': 3.19.0 - '@shikijs/transformers': 3.19.0 - '@shikijs/types': 3.19.0 + '@docsearch/css': 4.6.0 + '@docsearch/js': 4.6.0 + '@docsearch/sidepanel-js': 4.6.0 + '@iconify-json/simple-icons': 1.2.74 + '@shikijs/core': 3.23.0 + '@shikijs/transformers': 3.23.0 + '@shikijs/types': 3.23.0 '@types/markdown-it': 14.1.2 - '@vitejs/plugin-vue': 6.0.2(vite@7.2.6)(vue@3.5.25) - '@vue/devtools-api': 8.0.5 - '@vue/shared': 3.5.25 - '@vueuse/core': 14.1.0(vue@3.5.25) - '@vueuse/integrations': 14.1.0(focus-trap@7.6.6)(vue@3.5.25) - focus-trap: 7.6.6 + '@vitejs/plugin-vue': 6.0.5(vite@7.3.1)(vue@3.5.30) + '@vue/devtools-api': 8.1.0 + '@vue/shared': 3.5.30 + '@vueuse/core': 14.2.1(vue@3.5.30) + '@vueuse/integrations': 14.2.1(focus-trap@7.8.0)(vue@3.5.30) + focus-trap: 7.8.0 mark.js: 8.11.1 minisearch: 7.2.0 - shiki: 3.19.0 - vite: 7.2.6 - vue: 3.5.25 + shiki: 3.23.0 + vite: 7.3.1 + vue: 3.5.30 optionalDependencies: - postcss: 8.5.6 + postcss: 8.5.8 transitivePeerDependencies: - '@types/node' - async-validator @@ -1729,13 +1725,13 @@ snapshots: - universal-cookie - yaml - vue@3.5.25: + vue@3.5.30: dependencies: - '@vue/compiler-dom': 3.5.25 - '@vue/compiler-sfc': 3.5.25 - '@vue/runtime-dom': 3.5.25 - '@vue/server-renderer': 3.5.25(vue@3.5.25) - '@vue/shared': 3.5.25 + '@vue/compiler-dom': 3.5.30 + '@vue/compiler-sfc': 3.5.30 + '@vue/runtime-dom': 3.5.30 + '@vue/server-renderer': 3.5.30(vue@3.5.30) + '@vue/shared': 3.5.30 which@2.0.2: dependencies: From 655a1f4ec8cadca462070bd790b54119dc460d4b Mon Sep 17 00:00:00 2001 From: adithya Date: Mon, 16 Mar 2026 00:01:28 +0530 Subject: [PATCH 162/279] fix: More details in contributing --- CONTRIBUTING.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 23018349..47be9ebb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -100,11 +100,19 @@ Run pytest: pytest ``` +## Detailed Guidelines + +A detailed form management guidelines are available in the [Fork Management](./docs/08-reference/03-fork-management.md) + # Documentation Documentation is written as markdown files, and placed inside the `docs/` directory. There are multiple sub directories under `docs/`, and be sure to place the `.md` file in the relevant sub directory if you are adding a new page. -If you want to include any image in the markdown file, place them in the `docs/images/` folder, and add a relative link in the `.md` file. +If you want to include any image in the markdown file, place them in the `docs/images/` folder, and add a relative link in the `.md` file. For example if there is a `diagram.png` in the `docs/images/` directory, which has to be shown in a markdown file called `docs/01-getting-started/01-choosing-a-deployment-method.md` the image has to be referenced as, + +``` +![A diagram](../images/diagram.png) +``` Frappe Docker also have a static site version of the documentation, which is made using the same `.md` files in the `docs/` directory. Build pipeline uses [VitePress](https://vitepress.dev/) as the Static Site builder, which is a JavaScript (TypeScript) static site builder. Note that to contribute to the documentation JavaScript or VitePress knowledge is not needed. Updating the `.md` file is enough. From c1e545f3e530089d4fb276dc185ba3772b5c1369 Mon Sep 17 00:00:00 2001 From: adithya Date: Mon, 16 Mar 2026 00:02:01 +0530 Subject: [PATCH 163/279] 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 +--- From 57287e9cff08793c03a8c68507f5d3a79e795de7 Mon Sep 17 00:00:00 2001 From: Rin Date: Mon, 16 Mar 2026 23:11:41 +0700 Subject: [PATCH 164/279] Refactor: Move shared security headers into a snippet and include it in server and files location blocks. --- resources/core/nginx/nginx-template.conf | 12 ++---------- resources/core/nginx/security_headers.conf | 5 +++++ 2 files changed, 7 insertions(+), 10 deletions(-) create mode 100644 resources/core/nginx/security_headers.conf diff --git a/resources/core/nginx/nginx-template.conf b/resources/core/nginx/nginx-template.conf index 8aaf0782..f07d5e16 100644 --- a/resources/core/nginx/nginx-template.conf +++ b/resources/core/nginx/nginx-template.conf @@ -21,11 +21,7 @@ server { proxy_buffers 4 256k; proxy_busy_buffers_size 256k; - add_header X-Frame-Options "SAMEORIGIN" always; - add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always; - add_header X-Content-Type-Options nosniff always; - add_header X-XSS-Protection "1; mode=block" always; - add_header Referrer-Policy "same-origin, strict-origin-when-cross-origin" always; + include resources/core/nginx/security_headers.conf; set_real_ip_from ${UPSTREAM_REAL_IP_ADDRESS}; real_ip_header ${UPSTREAM_REAL_IP_HEADER}; @@ -59,11 +55,7 @@ server { rewrite ^(.+)\.html$ $1 permanent; location ~ ^/files/.*.(htm|html|svg|xml) { - add_header X-Frame-Options "SAMEORIGIN" always; - add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always; - add_header X-Content-Type-Options nosniff always; - add_header X-XSS-Protection "1; mode=block" always; - add_header Referrer-Policy "same-origin, strict-origin-when-cross-origin" always; + include resources/core/nginx/security_headers.conf; add_header Content-disposition "attachment"; try_files /${FRAPPE_SITE_NAME_HEADER}/public/$uri @webserver; } diff --git a/resources/core/nginx/security_headers.conf b/resources/core/nginx/security_headers.conf new file mode 100644 index 00000000..ccb54267 --- /dev/null +++ b/resources/core/nginx/security_headers.conf @@ -0,0 +1,5 @@ +add_header X-Frame-Options "SAMEORIGIN" always; +add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always; +add_header X-Content-Type-Options nosniff always; +add_header X-XSS-Protection "1; mode=block" always; +add_header Referrer-Policy "same-origin, strict-origin-when-cross-origin" always; From c40113923c6262e90f6d10c553768f1eaaf5d715 Mon Sep 17 00:00:00 2001 From: Rocket-Quack <202538874+Rocket-Quack@users.noreply.github.com> Date: Tue, 17 Mar 2026 15:52:42 +0100 Subject: [PATCH 165/279] refactor(nginx): include headers snippet via correct runtime path --- resources/core/nginx/nginx-template.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/core/nginx/nginx-template.conf b/resources/core/nginx/nginx-template.conf index f07d5e16..2172ebb7 100644 --- a/resources/core/nginx/nginx-template.conf +++ b/resources/core/nginx/nginx-template.conf @@ -21,7 +21,7 @@ server { proxy_buffers 4 256k; proxy_busy_buffers_size 256k; - include resources/core/nginx/security_headers.conf; + include /etc/nginx/snippets/security_headers.conf; set_real_ip_from ${UPSTREAM_REAL_IP_ADDRESS}; real_ip_header ${UPSTREAM_REAL_IP_HEADER}; @@ -55,7 +55,7 @@ server { rewrite ^(.+)\.html$ $1 permanent; location ~ ^/files/.*.(htm|html|svg|xml) { - include resources/core/nginx/security_headers.conf; + include /etc/nginx/snippets/security_headers.conf; add_header Content-disposition "attachment"; try_files /${FRAPPE_SITE_NAME_HEADER}/public/$uri @webserver; } From 00c347594316f0ae916ee15ee65846f7e3dc480d Mon Sep 17 00:00:00 2001 From: Rocket-Quack <202538874+Rocket-Quack@users.noreply.github.com> Date: Tue, 17 Mar 2026 15:54:01 +0100 Subject: [PATCH 166/279] build(docker images): add nginx security headers snippet in production and custom images --- images/custom/Containerfile | 4 ++++ images/production/Containerfile | 3 +++ 2 files changed, 7 insertions(+) diff --git a/images/custom/Containerfile b/images/custom/Containerfile index eefa4e6c..b72af438 100644 --- a/images/custom/Containerfile +++ b/images/custom/Containerfile @@ -63,6 +63,7 @@ RUN useradd -ms /bin/bash frappe \ # Clean up && rm -rf /var/lib/apt/lists/* \ && rm -fr /etc/nginx/sites-enabled/default \ + && mkdir -p /etc/nginx/snippets \ && pip3 install frappe-bench \ # Fixes for non-root nginx and logs to stdout && sed -i '/user www-data/d' /etc/nginx/nginx.conf \ @@ -70,12 +71,15 @@ RUN useradd -ms /bin/bash frappe \ && touch /run/nginx.pid \ && chown -R frappe:frappe /etc/nginx/conf.d \ && chown -R frappe:frappe /etc/nginx/nginx.conf \ + && chown -R frappe:frappe /etc/nginx/snippets \ && chown -R frappe:frappe /var/log/nginx \ && chown -R frappe:frappe /var/lib/nginx \ && chown -R frappe:frappe /run/nginx.pid \ && chmod 755 /usr/local/bin/nginx-entrypoint.sh \ && chmod 644 /templates/nginx/frappe.conf.template +COPY resources/core/nginx/security_headers.conf /etc/nginx/snippets/security_headers.conf + FROM base AS builder RUN apt-get update \ diff --git a/images/production/Containerfile b/images/production/Containerfile index 4a8c7f4c..17f1573d 100644 --- a/images/production/Containerfile +++ b/images/production/Containerfile @@ -60,6 +60,7 @@ RUN useradd -ms /bin/bash frappe \ # Clean up && rm -rf /var/lib/apt/lists/* \ && rm -fr /etc/nginx/sites-enabled/default \ + && mkdir -p /etc/nginx/snippets \ && pip3 install frappe-bench \ # Fixes for non-root nginx and logs to stdout && sed -i '/user www-data/d' /etc/nginx/nginx.conf \ @@ -67,12 +68,14 @@ RUN useradd -ms /bin/bash frappe \ && touch /run/nginx.pid \ && chown -R frappe:frappe /etc/nginx/conf.d \ && chown -R frappe:frappe /etc/nginx/nginx.conf \ + && chown -R frappe:frappe /etc/nginx/snippets \ && chown -R frappe:frappe /var/log/nginx \ && chown -R frappe:frappe /var/lib/nginx \ && chown -R frappe:frappe /run/nginx.pid COPY resources/core/nginx/nginx-template.conf /templates/nginx/frappe.conf.template COPY resources/core/nginx/nginx-entrypoint.sh /usr/local/bin/nginx-entrypoint.sh +COPY resources/core/nginx/security_headers.conf /etc/nginx/snippets/security_headers.conf FROM base AS build From 3ffa8b720c9992f9d48130f394cc4a15b8610a8f Mon Sep 17 00:00:00 2001 From: Rocket-Quack <202538874+Rocket-Quack@users.noreply.github.com> Date: Tue, 17 Mar 2026 16:08:25 +0100 Subject: [PATCH 167/279] test(nginx): add regression coverage for /files headers --- tests/test_frappe_docker.py | 24 +++++++++++++++++++++- tests/utils.py | 40 +++++++++++++++++++++++-------------- 2 files changed, 48 insertions(+), 16 deletions(-) diff --git a/tests/test_frappe_docker.py b/tests/test_frappe_docker.py index 85e6f1e8..fbf40b5d 100644 --- a/tests/test_frappe_docker.py +++ b/tests/test_frappe_docker.py @@ -5,7 +5,7 @@ from typing import Any import pytest from tests.conftest import S3ServiceResult -from tests.utils import Compose, check_url_content +from tests.utils import Compose, check_url_content, wait_for_url BACKEND_SERVICES = ( "backend", @@ -81,6 +81,28 @@ def test_files_reachable(frappe_site: str, tmp_path: Path, compose: Compose): ) +def test_files_html_security_headers( + frappe_site: str, tmp_path: Path, compose: Compose +): + file_path = tmp_path / "testfile.html" + file_path.write_text("This is a Frappe Docker test html file") + + compose( + "cp", + str(file_path), + f"backend:/home/frappe/frappe-bench/sites/{frappe_site}/public/files/", + ) + + response = wait_for_url( + url=f"http://127.0.0.1/files/{file_path.name}", + site_name=frappe_site, + ) + + assert response.headers["Content-Disposition"] == "attachment" + assert response.headers["X-Frame-Options"] == "SAMEORIGIN" + assert response.headers["X-Content-Type-Options"] == "nosniff" + + @pytest.mark.parametrize("service", BACKEND_SERVICES) @pytest.mark.usefixtures("frappe_site") def test_frappe_connections_in_backends( diff --git a/tests/utils.py b/tests/utils.py index fc12198b..a58be1bd 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -4,6 +4,7 @@ import subprocess import sys import time from contextlib import suppress +from http.client import HTTPResponse from typing import Callable, Optional from urllib.error import HTTPError, URLError from urllib.request import Request, urlopen @@ -59,24 +60,11 @@ class Compose: def check_url_content( url: str, callback: Callable[[str], Optional[str]], site_name: str ): - request = Request(url, headers={"Host": site_name}) - - # This is needed to check https override - ctx = ssl.create_default_context() - ctx.check_hostname = False - ctx.verify_mode = ssl.CERT_NONE - for _ in range(100): try: - response = urlopen(request, context=ctx) - - except HTTPError as exc: - if exc.code not in (404, 502): - raise - - except URLError: + response = wait_for_url(url=url, site_name=site_name, attempts=1) + except RuntimeError: pass - else: text: str = response.read().decode() ret = callback(text) @@ -86,4 +74,26 @@ def check_url_content( time.sleep(0.1) + raise RuntimeError(f"Couldn't verify expected content from {url}") + + +def wait_for_url(url: str, site_name: str, attempts: int = 100) -> HTTPResponse: + request = Request(url, headers={"Host": site_name}) + + # This is needed to check https override + ctx = ssl.create_default_context() + ctx.check_hostname = False + ctx.verify_mode = ssl.CERT_NONE + + for _ in range(attempts): + try: + return urlopen(request, context=ctx) + except HTTPError as exc: + if exc.code not in (404, 502): + raise + except URLError: + pass + + time.sleep(0.1) + raise RuntimeError(f"Couldn't ping {url}") From 730e31805b1b997b3b2ac8cf643b0798bbe3de13 Mon Sep 17 00:00:00 2001 From: RinZ27 <222222878+RinZ27@users.noreply.github.com> Date: Wed, 18 Mar 2026 10:14:54 +0700 Subject: [PATCH 168/279] style: fix linting issues with black --- tests/test_frappe_docker.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/test_frappe_docker.py b/tests/test_frappe_docker.py index fbf40b5d..6eadeb53 100644 --- a/tests/test_frappe_docker.py +++ b/tests/test_frappe_docker.py @@ -85,7 +85,9 @@ def test_files_html_security_headers( frappe_site: str, tmp_path: Path, compose: Compose ): file_path = tmp_path / "testfile.html" - file_path.write_text("This is a Frappe Docker test html file") + file_path.write_text( + "This is a Frappe Docker test html file" + ) compose( "cp", From 010278ea2e6bbdf822bdcb998ab2d332bd4beaa2 Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 18 Mar 2026 05:26:24 +0000 Subject: [PATCH 169/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 706243ac..1e4d8b76 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v16.9.1 +ERPNEXT_VERSION=v16.10.0 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index 865a7af0..3a9f27e5 100644 --- a/pwd.yml +++ b/pwd.yml @@ -1,6 +1,6 @@ services: backend: - image: frappe/erpnext:v16.9.1 + image: frappe/erpnext:v16.10.0 networks: - frappe_network deploy: @@ -16,7 +16,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v16.9.1 + image: frappe/erpnext:v16.10.0 networks: - frappe_network deploy: @@ -45,7 +45,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v16.9.1 + image: frappe/erpnext:v16.10.0 networks: - frappe_network deploy: @@ -100,7 +100,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v16.9.1 + image: frappe/erpnext:v16.10.0 networks: - frappe_network depends_on: @@ -126,7 +126,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v16.9.1 + image: frappe/erpnext:v16.10.0 networks: - frappe_network deploy: @@ -145,7 +145,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v16.9.1 + image: frappe/erpnext:v16.10.0 networks: - frappe_network deploy: @@ -182,7 +182,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v16.9.1 + image: frappe/erpnext:v16.10.0 networks: - frappe_network deploy: @@ -196,7 +196,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v16.9.1 + image: frappe/erpnext:v16.10.0 networks: - frappe_network deploy: From c5af709a325917dbe229b998436286767867d54c Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 18 Mar 2026 14:11:27 +0000 Subject: [PATCH 170/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 1e4d8b76..344e2b21 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v16.10.0 +ERPNEXT_VERSION=v16.10.1 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index 3a9f27e5..9415d066 100644 --- a/pwd.yml +++ b/pwd.yml @@ -1,6 +1,6 @@ services: backend: - image: frappe/erpnext:v16.10.0 + image: frappe/erpnext:v16.10.1 networks: - frappe_network deploy: @@ -16,7 +16,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v16.10.0 + image: frappe/erpnext:v16.10.1 networks: - frappe_network deploy: @@ -45,7 +45,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v16.10.0 + image: frappe/erpnext:v16.10.1 networks: - frappe_network deploy: @@ -100,7 +100,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v16.10.0 + image: frappe/erpnext:v16.10.1 networks: - frappe_network depends_on: @@ -126,7 +126,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v16.10.0 + image: frappe/erpnext:v16.10.1 networks: - frappe_network deploy: @@ -145,7 +145,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v16.10.0 + image: frappe/erpnext:v16.10.1 networks: - frappe_network deploy: @@ -182,7 +182,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v16.10.0 + image: frappe/erpnext:v16.10.1 networks: - frappe_network deploy: @@ -196,7 +196,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v16.10.0 + image: frappe/erpnext:v16.10.1 networks: - frappe_network deploy: From 1b8ddeadfdc50df32fd7868865ddfa4efa6e4251 Mon Sep 17 00:00:00 2001 From: RocketQuack <202538874+Rocket-Quack@users.noreply.github.com> Date: Thu, 19 Mar 2026 11:56:06 +0100 Subject: [PATCH 171/279] chore(packages): pin vitepress-sidebar version --- docs/package.json | 2 +- docs/pnpm-lock.yaml | 1859 ++++++++++++++++++++++++++++--------------- 2 files changed, 1228 insertions(+), 633 deletions(-) diff --git a/docs/package.json b/docs/package.json index 73b65329..91fd37bb 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,7 +1,7 @@ { "devDependencies": { "vitepress": "2.0.0-alpha.16", - "vitepress-sidebar": "^1.33.1" + "vitepress-sidebar": "1.33.1" }, "scripts": { "docs:dev": "vitepress dev", diff --git a/docs/pnpm-lock.yaml b/docs/pnpm-lock.yaml index 9881ec77..7497803e 100644 --- a/docs/pnpm-lock.yaml +++ b/docs/pnpm-lock.yaml @@ -1,469 +1,758 @@ -lockfileVersion: '9.0' +lockfileVersion: "9.0" settings: autoInstallPeers: true excludeLinksFromLockfile: false importers: - .: devDependencies: vitepress: specifier: 2.0.0-alpha.16 version: 2.0.0-alpha.16(postcss@8.5.8) vitepress-sidebar: - specifier: ^1.33.1 + specifier: 1.33.1 version: 1.33.1 packages: + "@babel/helper-string-parser@7.27.1": + resolution: + { + integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==, + } + engines: { node: ">=6.9.0" } - '@babel/helper-string-parser@7.27.1': - resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} - engines: {node: '>=6.9.0'} + "@babel/helper-validator-identifier@7.28.5": + resolution: + { + integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==, + } + engines: { node: ">=6.9.0" } - '@babel/helper-validator-identifier@7.28.5': - resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} - engines: {node: '>=6.9.0'} - - '@babel/parser@7.29.0': - resolution: {integrity: sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==} - engines: {node: '>=6.0.0'} + "@babel/parser@7.29.0": + resolution: + { + integrity: sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==, + } + engines: { node: ">=6.0.0" } hasBin: true - '@babel/types@7.29.0': - resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} - engines: {node: '>=6.9.0'} + "@babel/types@7.29.0": + resolution: + { + integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==, + } + engines: { node: ">=6.9.0" } - '@docsearch/css@4.6.0': - resolution: {integrity: sha512-YlcAimkXclvqta47g47efzCM5CFxDwv2ClkDfEs/fC/Ak0OxPH2b3czwa4o8O1TRBf+ujFF2RiUwszz2fPVNJQ==} + "@docsearch/css@4.6.0": + resolution: + { + integrity: sha512-YlcAimkXclvqta47g47efzCM5CFxDwv2ClkDfEs/fC/Ak0OxPH2b3czwa4o8O1TRBf+ujFF2RiUwszz2fPVNJQ==, + } - '@docsearch/js@4.6.0': - resolution: {integrity: sha512-9/rbgkm/BgTq46cwxIohvSAz3koOFjnPpg0mwkJItAfzKbQIj+310PvwtgUY1YITDuGCag6yOL50GW2DBkaaBw==} + "@docsearch/js@4.6.0": + resolution: + { + integrity: sha512-9/rbgkm/BgTq46cwxIohvSAz3koOFjnPpg0mwkJItAfzKbQIj+310PvwtgUY1YITDuGCag6yOL50GW2DBkaaBw==, + } - '@docsearch/sidepanel-js@4.6.0': - resolution: {integrity: sha512-lFT5KLwlzUmpoGArCScNoK41l9a22JYsEPwBzMrz+/ILVR5Ax87UphCuiyDFQWEvEmbwzn/kJx5W/O5BUlN1Rw==} + "@docsearch/sidepanel-js@4.6.0": + resolution: + { + integrity: sha512-lFT5KLwlzUmpoGArCScNoK41l9a22JYsEPwBzMrz+/ILVR5Ax87UphCuiyDFQWEvEmbwzn/kJx5W/O5BUlN1Rw==, + } - '@esbuild/aix-ppc64@0.27.4': - resolution: {integrity: sha512-cQPwL2mp2nSmHHJlCyoXgHGhbEPMrEEU5xhkcy3Hs/O7nGZqEpZ2sUtLaL9MORLtDfRvVl2/3PAuEkYZH0Ty8Q==} - engines: {node: '>=18'} + "@esbuild/aix-ppc64@0.27.4": + resolution: + { + integrity: sha512-cQPwL2mp2nSmHHJlCyoXgHGhbEPMrEEU5xhkcy3Hs/O7nGZqEpZ2sUtLaL9MORLtDfRvVl2/3PAuEkYZH0Ty8Q==, + } + engines: { node: ">=18" } cpu: [ppc64] os: [aix] - '@esbuild/android-arm64@0.27.4': - resolution: {integrity: sha512-gdLscB7v75wRfu7QSm/zg6Rx29VLdy9eTr2t44sfTW7CxwAtQghZ4ZnqHk3/ogz7xao0QAgrkradbBzcqFPasw==} - engines: {node: '>=18'} + "@esbuild/android-arm64@0.27.4": + resolution: + { + integrity: sha512-gdLscB7v75wRfu7QSm/zg6Rx29VLdy9eTr2t44sfTW7CxwAtQghZ4ZnqHk3/ogz7xao0QAgrkradbBzcqFPasw==, + } + engines: { node: ">=18" } cpu: [arm64] os: [android] - '@esbuild/android-arm@0.27.4': - resolution: {integrity: sha512-X9bUgvxiC8CHAGKYufLIHGXPJWnr0OCdR0anD2e21vdvgCI8lIfqFbnoeOz7lBjdrAGUhqLZLcQo6MLhTO2DKQ==} - engines: {node: '>=18'} + "@esbuild/android-arm@0.27.4": + resolution: + { + integrity: sha512-X9bUgvxiC8CHAGKYufLIHGXPJWnr0OCdR0anD2e21vdvgCI8lIfqFbnoeOz7lBjdrAGUhqLZLcQo6MLhTO2DKQ==, + } + engines: { node: ">=18" } cpu: [arm] os: [android] - '@esbuild/android-x64@0.27.4': - resolution: {integrity: sha512-PzPFnBNVF292sfpfhiyiXCGSn9HZg5BcAz+ivBuSsl6Rk4ga1oEXAamhOXRFyMcjwr2DVtm40G65N3GLeH1Lvw==} - engines: {node: '>=18'} + "@esbuild/android-x64@0.27.4": + resolution: + { + integrity: sha512-PzPFnBNVF292sfpfhiyiXCGSn9HZg5BcAz+ivBuSsl6Rk4ga1oEXAamhOXRFyMcjwr2DVtm40G65N3GLeH1Lvw==, + } + engines: { node: ">=18" } cpu: [x64] os: [android] - '@esbuild/darwin-arm64@0.27.4': - resolution: {integrity: sha512-b7xaGIwdJlht8ZFCvMkpDN6uiSmnxxK56N2GDTMYPr2/gzvfdQN8rTfBsvVKmIVY/X7EM+/hJKEIbbHs9oA4tQ==} - engines: {node: '>=18'} + "@esbuild/darwin-arm64@0.27.4": + resolution: + { + integrity: sha512-b7xaGIwdJlht8ZFCvMkpDN6uiSmnxxK56N2GDTMYPr2/gzvfdQN8rTfBsvVKmIVY/X7EM+/hJKEIbbHs9oA4tQ==, + } + engines: { node: ">=18" } cpu: [arm64] os: [darwin] - '@esbuild/darwin-x64@0.27.4': - resolution: {integrity: sha512-sR+OiKLwd15nmCdqpXMnuJ9W2kpy0KigzqScqHI3Hqwr7IXxBp3Yva+yJwoqh7rE8V77tdoheRYataNKL4QrPw==} - engines: {node: '>=18'} + "@esbuild/darwin-x64@0.27.4": + resolution: + { + integrity: sha512-sR+OiKLwd15nmCdqpXMnuJ9W2kpy0KigzqScqHI3Hqwr7IXxBp3Yva+yJwoqh7rE8V77tdoheRYataNKL4QrPw==, + } + engines: { node: ">=18" } cpu: [x64] os: [darwin] - '@esbuild/freebsd-arm64@0.27.4': - resolution: {integrity: sha512-jnfpKe+p79tCnm4GVav68A7tUFeKQwQyLgESwEAUzyxk/TJr4QdGog9sqWNcUbr/bZt/O/HXouspuQDd9JxFSw==} - engines: {node: '>=18'} + "@esbuild/freebsd-arm64@0.27.4": + resolution: + { + integrity: sha512-jnfpKe+p79tCnm4GVav68A7tUFeKQwQyLgESwEAUzyxk/TJr4QdGog9sqWNcUbr/bZt/O/HXouspuQDd9JxFSw==, + } + engines: { node: ">=18" } cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-x64@0.27.4': - resolution: {integrity: sha512-2kb4ceA/CpfUrIcTUl1wrP/9ad9Atrp5J94Lq69w7UwOMolPIGrfLSvAKJp0RTvkPPyn6CIWrNy13kyLikZRZQ==} - engines: {node: '>=18'} + "@esbuild/freebsd-x64@0.27.4": + resolution: + { + integrity: sha512-2kb4ceA/CpfUrIcTUl1wrP/9ad9Atrp5J94Lq69w7UwOMolPIGrfLSvAKJp0RTvkPPyn6CIWrNy13kyLikZRZQ==, + } + engines: { node: ">=18" } cpu: [x64] os: [freebsd] - '@esbuild/linux-arm64@0.27.4': - resolution: {integrity: sha512-7nQOttdzVGth1iz57kxg9uCz57dxQLHWxopL6mYuYthohPKEK0vU0C3O21CcBK6KDlkYVcnDXY099HcCDXd9dA==} - engines: {node: '>=18'} + "@esbuild/linux-arm64@0.27.4": + resolution: + { + integrity: sha512-7nQOttdzVGth1iz57kxg9uCz57dxQLHWxopL6mYuYthohPKEK0vU0C3O21CcBK6KDlkYVcnDXY099HcCDXd9dA==, + } + engines: { node: ">=18" } cpu: [arm64] os: [linux] - '@esbuild/linux-arm@0.27.4': - resolution: {integrity: sha512-aBYgcIxX/wd5n2ys0yESGeYMGF+pv6g0DhZr3G1ZG4jMfruU9Tl1i2Z+Wnj9/KjGz1lTLCcorqE2viePZqj4Eg==} - engines: {node: '>=18'} + "@esbuild/linux-arm@0.27.4": + resolution: + { + integrity: sha512-aBYgcIxX/wd5n2ys0yESGeYMGF+pv6g0DhZr3G1ZG4jMfruU9Tl1i2Z+Wnj9/KjGz1lTLCcorqE2viePZqj4Eg==, + } + engines: { node: ">=18" } cpu: [arm] os: [linux] - '@esbuild/linux-ia32@0.27.4': - resolution: {integrity: sha512-oPtixtAIzgvzYcKBQM/qZ3R+9TEUd1aNJQu0HhGyqtx6oS7qTpvjheIWBbes4+qu1bNlo2V4cbkISr8q6gRBFA==} - engines: {node: '>=18'} + "@esbuild/linux-ia32@0.27.4": + resolution: + { + integrity: sha512-oPtixtAIzgvzYcKBQM/qZ3R+9TEUd1aNJQu0HhGyqtx6oS7qTpvjheIWBbes4+qu1bNlo2V4cbkISr8q6gRBFA==, + } + engines: { node: ">=18" } cpu: [ia32] os: [linux] - '@esbuild/linux-loong64@0.27.4': - resolution: {integrity: sha512-8mL/vh8qeCoRcFH2nM8wm5uJP+ZcVYGGayMavi8GmRJjuI3g1v6Z7Ni0JJKAJW+m0EtUuARb6Lmp4hMjzCBWzA==} - engines: {node: '>=18'} + "@esbuild/linux-loong64@0.27.4": + resolution: + { + integrity: sha512-8mL/vh8qeCoRcFH2nM8wm5uJP+ZcVYGGayMavi8GmRJjuI3g1v6Z7Ni0JJKAJW+m0EtUuARb6Lmp4hMjzCBWzA==, + } + engines: { node: ">=18" } cpu: [loong64] os: [linux] - '@esbuild/linux-mips64el@0.27.4': - resolution: {integrity: sha512-1RdrWFFiiLIW7LQq9Q2NES+HiD4NyT8Itj9AUeCl0IVCA459WnPhREKgwrpaIfTOe+/2rdntisegiPWn/r/aAw==} - engines: {node: '>=18'} + "@esbuild/linux-mips64el@0.27.4": + resolution: + { + integrity: sha512-1RdrWFFiiLIW7LQq9Q2NES+HiD4NyT8Itj9AUeCl0IVCA459WnPhREKgwrpaIfTOe+/2rdntisegiPWn/r/aAw==, + } + engines: { node: ">=18" } cpu: [mips64el] os: [linux] - '@esbuild/linux-ppc64@0.27.4': - resolution: {integrity: sha512-tLCwNG47l3sd9lpfyx9LAGEGItCUeRCWeAx6x2Jmbav65nAwoPXfewtAdtbtit/pJFLUWOhpv0FpS6GQAmPrHA==} - engines: {node: '>=18'} + "@esbuild/linux-ppc64@0.27.4": + resolution: + { + integrity: sha512-tLCwNG47l3sd9lpfyx9LAGEGItCUeRCWeAx6x2Jmbav65nAwoPXfewtAdtbtit/pJFLUWOhpv0FpS6GQAmPrHA==, + } + engines: { node: ">=18" } cpu: [ppc64] os: [linux] - '@esbuild/linux-riscv64@0.27.4': - resolution: {integrity: sha512-BnASypppbUWyqjd1KIpU4AUBiIhVr6YlHx/cnPgqEkNoVOhHg+YiSVxM1RLfiy4t9cAulbRGTNCKOcqHrEQLIw==} - engines: {node: '>=18'} + "@esbuild/linux-riscv64@0.27.4": + resolution: + { + integrity: sha512-BnASypppbUWyqjd1KIpU4AUBiIhVr6YlHx/cnPgqEkNoVOhHg+YiSVxM1RLfiy4t9cAulbRGTNCKOcqHrEQLIw==, + } + engines: { node: ">=18" } cpu: [riscv64] os: [linux] - '@esbuild/linux-s390x@0.27.4': - resolution: {integrity: sha512-+eUqgb/Z7vxVLezG8bVB9SfBie89gMueS+I0xYh2tJdw3vqA/0ImZJ2ROeWwVJN59ihBeZ7Tu92dF/5dy5FttA==} - engines: {node: '>=18'} + "@esbuild/linux-s390x@0.27.4": + resolution: + { + integrity: sha512-+eUqgb/Z7vxVLezG8bVB9SfBie89gMueS+I0xYh2tJdw3vqA/0ImZJ2ROeWwVJN59ihBeZ7Tu92dF/5dy5FttA==, + } + engines: { node: ">=18" } cpu: [s390x] os: [linux] - '@esbuild/linux-x64@0.27.4': - resolution: {integrity: sha512-S5qOXrKV8BQEzJPVxAwnryi2+Iq5pB40gTEIT69BQONqR7JH1EPIcQ/Uiv9mCnn05jff9umq/5nqzxlqTOg9NA==} - engines: {node: '>=18'} + "@esbuild/linux-x64@0.27.4": + resolution: + { + integrity: sha512-S5qOXrKV8BQEzJPVxAwnryi2+Iq5pB40gTEIT69BQONqR7JH1EPIcQ/Uiv9mCnn05jff9umq/5nqzxlqTOg9NA==, + } + engines: { node: ">=18" } cpu: [x64] os: [linux] - '@esbuild/netbsd-arm64@0.27.4': - resolution: {integrity: sha512-xHT8X4sb0GS8qTqiwzHqpY00C95DPAq7nAwX35Ie/s+LO9830hrMd3oX0ZMKLvy7vsonee73x0lmcdOVXFzd6Q==} - engines: {node: '>=18'} + "@esbuild/netbsd-arm64@0.27.4": + resolution: + { + integrity: sha512-xHT8X4sb0GS8qTqiwzHqpY00C95DPAq7nAwX35Ie/s+LO9830hrMd3oX0ZMKLvy7vsonee73x0lmcdOVXFzd6Q==, + } + engines: { node: ">=18" } cpu: [arm64] os: [netbsd] - '@esbuild/netbsd-x64@0.27.4': - resolution: {integrity: sha512-RugOvOdXfdyi5Tyv40kgQnI0byv66BFgAqjdgtAKqHoZTbTF2QqfQrFwa7cHEORJf6X2ht+l9ABLMP0dnKYsgg==} - engines: {node: '>=18'} + "@esbuild/netbsd-x64@0.27.4": + resolution: + { + integrity: sha512-RugOvOdXfdyi5Tyv40kgQnI0byv66BFgAqjdgtAKqHoZTbTF2QqfQrFwa7cHEORJf6X2ht+l9ABLMP0dnKYsgg==, + } + engines: { node: ">=18" } cpu: [x64] os: [netbsd] - '@esbuild/openbsd-arm64@0.27.4': - resolution: {integrity: sha512-2MyL3IAaTX+1/qP0O1SwskwcwCoOI4kV2IBX1xYnDDqthmq5ArrW94qSIKCAuRraMgPOmG0RDTA74mzYNQA9ow==} - engines: {node: '>=18'} + "@esbuild/openbsd-arm64@0.27.4": + resolution: + { + integrity: sha512-2MyL3IAaTX+1/qP0O1SwskwcwCoOI4kV2IBX1xYnDDqthmq5ArrW94qSIKCAuRraMgPOmG0RDTA74mzYNQA9ow==, + } + engines: { node: ">=18" } cpu: [arm64] os: [openbsd] - '@esbuild/openbsd-x64@0.27.4': - resolution: {integrity: sha512-u8fg/jQ5aQDfsnIV6+KwLOf1CmJnfu1ShpwqdwC0uA7ZPwFws55Ngc12vBdeUdnuWoQYx/SOQLGDcdlfXhYmXQ==} - engines: {node: '>=18'} + "@esbuild/openbsd-x64@0.27.4": + resolution: + { + integrity: sha512-u8fg/jQ5aQDfsnIV6+KwLOf1CmJnfu1ShpwqdwC0uA7ZPwFws55Ngc12vBdeUdnuWoQYx/SOQLGDcdlfXhYmXQ==, + } + engines: { node: ">=18" } cpu: [x64] os: [openbsd] - '@esbuild/openharmony-arm64@0.27.4': - resolution: {integrity: sha512-JkTZrl6VbyO8lDQO3yv26nNr2RM2yZzNrNHEsj9bm6dOwwu9OYN28CjzZkH57bh4w0I2F7IodpQvUAEd1mbWXg==} - engines: {node: '>=18'} + "@esbuild/openharmony-arm64@0.27.4": + resolution: + { + integrity: sha512-JkTZrl6VbyO8lDQO3yv26nNr2RM2yZzNrNHEsj9bm6dOwwu9OYN28CjzZkH57bh4w0I2F7IodpQvUAEd1mbWXg==, + } + engines: { node: ">=18" } cpu: [arm64] os: [openharmony] - '@esbuild/sunos-x64@0.27.4': - resolution: {integrity: sha512-/gOzgaewZJfeJTlsWhvUEmUG4tWEY2Spp5M20INYRg2ZKl9QPO3QEEgPeRtLjEWSW8FilRNacPOg8R1uaYkA6g==} - engines: {node: '>=18'} + "@esbuild/sunos-x64@0.27.4": + resolution: + { + integrity: sha512-/gOzgaewZJfeJTlsWhvUEmUG4tWEY2Spp5M20INYRg2ZKl9QPO3QEEgPeRtLjEWSW8FilRNacPOg8R1uaYkA6g==, + } + engines: { node: ">=18" } cpu: [x64] os: [sunos] - '@esbuild/win32-arm64@0.27.4': - resolution: {integrity: sha512-Z9SExBg2y32smoDQdf1HRwHRt6vAHLXcxD2uGgO/v2jK7Y718Ix4ndsbNMU/+1Qiem9OiOdaqitioZwxivhXYg==} - engines: {node: '>=18'} + "@esbuild/win32-arm64@0.27.4": + resolution: + { + integrity: sha512-Z9SExBg2y32smoDQdf1HRwHRt6vAHLXcxD2uGgO/v2jK7Y718Ix4ndsbNMU/+1Qiem9OiOdaqitioZwxivhXYg==, + } + engines: { node: ">=18" } cpu: [arm64] os: [win32] - '@esbuild/win32-ia32@0.27.4': - resolution: {integrity: sha512-DAyGLS0Jz5G5iixEbMHi5KdiApqHBWMGzTtMiJ72ZOLhbu/bzxgAe8Ue8CTS3n3HbIUHQz/L51yMdGMeoxXNJw==} - engines: {node: '>=18'} + "@esbuild/win32-ia32@0.27.4": + resolution: + { + integrity: sha512-DAyGLS0Jz5G5iixEbMHi5KdiApqHBWMGzTtMiJ72ZOLhbu/bzxgAe8Ue8CTS3n3HbIUHQz/L51yMdGMeoxXNJw==, + } + engines: { node: ">=18" } cpu: [ia32] os: [win32] - '@esbuild/win32-x64@0.27.4': - resolution: {integrity: sha512-+knoa0BDoeXgkNvvV1vvbZX4+hizelrkwmGJBdT17t8FNPwG2lKemmuMZlmaNQ3ws3DKKCxpb4zRZEIp3UxFCg==} - engines: {node: '>=18'} + "@esbuild/win32-x64@0.27.4": + resolution: + { + integrity: sha512-+knoa0BDoeXgkNvvV1vvbZX4+hizelrkwmGJBdT17t8FNPwG2lKemmuMZlmaNQ3ws3DKKCxpb4zRZEIp3UxFCg==, + } + engines: { node: ">=18" } cpu: [x64] os: [win32] - '@iconify-json/simple-icons@1.2.74': - resolution: {integrity: sha512-yqaohfY6jnYjTVpuTkaBQHrWbdUrQyWXhau0r/0EZiNWYXPX/P8WWwl1DoLH5CbvDjjcWQw5J0zADhgCUklOqA==} + "@iconify-json/simple-icons@1.2.74": + resolution: + { + integrity: sha512-yqaohfY6jnYjTVpuTkaBQHrWbdUrQyWXhau0r/0EZiNWYXPX/P8WWwl1DoLH5CbvDjjcWQw5J0zADhgCUklOqA==, + } - '@iconify/types@2.0.0': - resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} + "@iconify/types@2.0.0": + resolution: + { + integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==, + } - '@isaacs/balanced-match@4.0.1': - resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} - engines: {node: 20 || >=22} + "@isaacs/balanced-match@4.0.1": + resolution: + { + integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==, + } + engines: { node: 20 || >=22 } - '@isaacs/brace-expansion@5.0.0': - resolution: {integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==} - engines: {node: 20 || >=22} + "@isaacs/brace-expansion@5.0.0": + resolution: + { + integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==, + } + engines: { node: 20 || >=22 } - '@isaacs/cliui@8.0.2': - resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} - engines: {node: '>=12'} + "@isaacs/cliui@8.0.2": + resolution: + { + integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==, + } + engines: { node: ">=12" } - '@jridgewell/sourcemap-codec@1.5.5': - resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + "@jridgewell/sourcemap-codec@1.5.5": + resolution: + { + integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==, + } - '@rolldown/pluginutils@1.0.0-rc.2': - resolution: {integrity: sha512-izyXV/v+cHiRfozX62W9htOAvwMo4/bXKDrQ+vom1L1qRuexPock/7VZDAhnpHCLNejd3NJ6hiab+tO0D44Rgw==} + "@rolldown/pluginutils@1.0.0-rc.2": + resolution: + { + integrity: sha512-izyXV/v+cHiRfozX62W9htOAvwMo4/bXKDrQ+vom1L1qRuexPock/7VZDAhnpHCLNejd3NJ6hiab+tO0D44Rgw==, + } - '@rollup/rollup-android-arm-eabi@4.59.0': - resolution: {integrity: sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==} + "@rollup/rollup-android-arm-eabi@4.59.0": + resolution: + { + integrity: sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==, + } cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.59.0': - resolution: {integrity: sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==} + "@rollup/rollup-android-arm64@4.59.0": + resolution: + { + integrity: sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==, + } cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.59.0': - resolution: {integrity: sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==} + "@rollup/rollup-darwin-arm64@4.59.0": + resolution: + { + integrity: sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==, + } cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.59.0': - resolution: {integrity: sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==} + "@rollup/rollup-darwin-x64@4.59.0": + resolution: + { + integrity: sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==, + } cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.59.0': - resolution: {integrity: sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==} + "@rollup/rollup-freebsd-arm64@4.59.0": + resolution: + { + integrity: sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==, + } cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.59.0': - resolution: {integrity: sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==} + "@rollup/rollup-freebsd-x64@4.59.0": + resolution: + { + integrity: sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==, + } cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.59.0': - resolution: {integrity: sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==} + "@rollup/rollup-linux-arm-gnueabihf@4.59.0": + resolution: + { + integrity: sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==, + } cpu: [arm] os: [linux] libc: [glibc] - '@rollup/rollup-linux-arm-musleabihf@4.59.0': - resolution: {integrity: sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==} + "@rollup/rollup-linux-arm-musleabihf@4.59.0": + resolution: + { + integrity: sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==, + } cpu: [arm] os: [linux] libc: [musl] - '@rollup/rollup-linux-arm64-gnu@4.59.0': - resolution: {integrity: sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==} + "@rollup/rollup-linux-arm64-gnu@4.59.0": + resolution: + { + integrity: sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==, + } cpu: [arm64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-arm64-musl@4.59.0': - resolution: {integrity: sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==} + "@rollup/rollup-linux-arm64-musl@4.59.0": + resolution: + { + integrity: sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==, + } cpu: [arm64] os: [linux] libc: [musl] - '@rollup/rollup-linux-loong64-gnu@4.59.0': - resolution: {integrity: sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==} + "@rollup/rollup-linux-loong64-gnu@4.59.0": + resolution: + { + integrity: sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==, + } cpu: [loong64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-loong64-musl@4.59.0': - resolution: {integrity: sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==} + "@rollup/rollup-linux-loong64-musl@4.59.0": + resolution: + { + integrity: sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==, + } cpu: [loong64] os: [linux] libc: [musl] - '@rollup/rollup-linux-ppc64-gnu@4.59.0': - resolution: {integrity: sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==} + "@rollup/rollup-linux-ppc64-gnu@4.59.0": + resolution: + { + integrity: sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==, + } cpu: [ppc64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-ppc64-musl@4.59.0': - resolution: {integrity: sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==} + "@rollup/rollup-linux-ppc64-musl@4.59.0": + resolution: + { + integrity: sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==, + } cpu: [ppc64] os: [linux] libc: [musl] - '@rollup/rollup-linux-riscv64-gnu@4.59.0': - resolution: {integrity: sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==} + "@rollup/rollup-linux-riscv64-gnu@4.59.0": + resolution: + { + integrity: sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==, + } cpu: [riscv64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-riscv64-musl@4.59.0': - resolution: {integrity: sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==} + "@rollup/rollup-linux-riscv64-musl@4.59.0": + resolution: + { + integrity: sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==, + } cpu: [riscv64] os: [linux] libc: [musl] - '@rollup/rollup-linux-s390x-gnu@4.59.0': - resolution: {integrity: sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==} + "@rollup/rollup-linux-s390x-gnu@4.59.0": + resolution: + { + integrity: sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==, + } cpu: [s390x] os: [linux] libc: [glibc] - '@rollup/rollup-linux-x64-gnu@4.59.0': - resolution: {integrity: sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==} + "@rollup/rollup-linux-x64-gnu@4.59.0": + resolution: + { + integrity: sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==, + } cpu: [x64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-x64-musl@4.59.0': - resolution: {integrity: sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==} + "@rollup/rollup-linux-x64-musl@4.59.0": + resolution: + { + integrity: sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==, + } cpu: [x64] os: [linux] libc: [musl] - '@rollup/rollup-openbsd-x64@4.59.0': - resolution: {integrity: sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==} + "@rollup/rollup-openbsd-x64@4.59.0": + resolution: + { + integrity: sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==, + } cpu: [x64] os: [openbsd] - '@rollup/rollup-openharmony-arm64@4.59.0': - resolution: {integrity: sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==} + "@rollup/rollup-openharmony-arm64@4.59.0": + resolution: + { + integrity: sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==, + } cpu: [arm64] os: [openharmony] - '@rollup/rollup-win32-arm64-msvc@4.59.0': - resolution: {integrity: sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==} + "@rollup/rollup-win32-arm64-msvc@4.59.0": + resolution: + { + integrity: sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==, + } cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.59.0': - resolution: {integrity: sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==} + "@rollup/rollup-win32-ia32-msvc@4.59.0": + resolution: + { + integrity: sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==, + } cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-gnu@4.59.0': - resolution: {integrity: sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==} + "@rollup/rollup-win32-x64-gnu@4.59.0": + resolution: + { + integrity: sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==, + } cpu: [x64] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.59.0': - resolution: {integrity: sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==} + "@rollup/rollup-win32-x64-msvc@4.59.0": + resolution: + { + integrity: sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==, + } cpu: [x64] os: [win32] - '@shikijs/core@3.23.0': - resolution: {integrity: sha512-NSWQz0riNb67xthdm5br6lAkvpDJRTgB36fxlo37ZzM2yq0PQFFzbd8psqC2XMPgCzo1fW6cVi18+ArJ44wqgA==} + "@shikijs/core@3.23.0": + resolution: + { + integrity: sha512-NSWQz0riNb67xthdm5br6lAkvpDJRTgB36fxlo37ZzM2yq0PQFFzbd8psqC2XMPgCzo1fW6cVi18+ArJ44wqgA==, + } - '@shikijs/engine-javascript@3.23.0': - resolution: {integrity: sha512-aHt9eiGFobmWR5uqJUViySI1bHMqrAgamWE1TYSUoftkAeCCAiGawPMwM+VCadylQtF4V3VNOZ5LmfItH5f3yA==} + "@shikijs/engine-javascript@3.23.0": + resolution: + { + integrity: sha512-aHt9eiGFobmWR5uqJUViySI1bHMqrAgamWE1TYSUoftkAeCCAiGawPMwM+VCadylQtF4V3VNOZ5LmfItH5f3yA==, + } - '@shikijs/engine-oniguruma@3.23.0': - resolution: {integrity: sha512-1nWINwKXxKKLqPibT5f4pAFLej9oZzQTsby8942OTlsJzOBZ0MWKiwzMsd+jhzu8YPCHAswGnnN1YtQfirL35g==} + "@shikijs/engine-oniguruma@3.23.0": + resolution: + { + integrity: sha512-1nWINwKXxKKLqPibT5f4pAFLej9oZzQTsby8942OTlsJzOBZ0MWKiwzMsd+jhzu8YPCHAswGnnN1YtQfirL35g==, + } - '@shikijs/langs@3.23.0': - resolution: {integrity: sha512-2Ep4W3Re5aB1/62RSYQInK9mM3HsLeB91cHqznAJMuylqjzNVAVCMnNWRHFtcNHXsoNRayP9z1qj4Sq3nMqYXg==} + "@shikijs/langs@3.23.0": + resolution: + { + integrity: sha512-2Ep4W3Re5aB1/62RSYQInK9mM3HsLeB91cHqznAJMuylqjzNVAVCMnNWRHFtcNHXsoNRayP9z1qj4Sq3nMqYXg==, + } - '@shikijs/themes@3.23.0': - resolution: {integrity: sha512-5qySYa1ZgAT18HR/ypENL9cUSGOeI2x+4IvYJu4JgVJdizn6kG4ia5Q1jDEOi7gTbN4RbuYtmHh0W3eccOrjMA==} + "@shikijs/themes@3.23.0": + resolution: + { + integrity: sha512-5qySYa1ZgAT18HR/ypENL9cUSGOeI2x+4IvYJu4JgVJdizn6kG4ia5Q1jDEOi7gTbN4RbuYtmHh0W3eccOrjMA==, + } - '@shikijs/transformers@3.23.0': - resolution: {integrity: sha512-F9msZVxdF+krQNSdQ4V+Ja5QemeAoTQ2jxt7nJCwhDsdF1JWS3KxIQXA3lQbyKwS3J61oHRUSv4jYWv3CkaKTQ==} + "@shikijs/transformers@3.23.0": + resolution: + { + integrity: sha512-F9msZVxdF+krQNSdQ4V+Ja5QemeAoTQ2jxt7nJCwhDsdF1JWS3KxIQXA3lQbyKwS3J61oHRUSv4jYWv3CkaKTQ==, + } - '@shikijs/types@3.23.0': - resolution: {integrity: sha512-3JZ5HXOZfYjsYSk0yPwBrkupyYSLpAE26Qc0HLghhZNGTZg/SKxXIIgoxOpmmeQP0RRSDJTk1/vPfw9tbw+jSQ==} + "@shikijs/types@3.23.0": + resolution: + { + integrity: sha512-3JZ5HXOZfYjsYSk0yPwBrkupyYSLpAE26Qc0HLghhZNGTZg/SKxXIIgoxOpmmeQP0RRSDJTk1/vPfw9tbw+jSQ==, + } - '@shikijs/vscode-textmate@10.0.2': - resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} + "@shikijs/vscode-textmate@10.0.2": + resolution: + { + integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==, + } - '@types/estree@1.0.8': - resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + "@types/estree@1.0.8": + resolution: + { + integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==, + } - '@types/hast@3.0.4': - resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} + "@types/hast@3.0.4": + resolution: + { + integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==, + } - '@types/linkify-it@5.0.0': - resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==} + "@types/linkify-it@5.0.0": + resolution: + { + integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==, + } - '@types/markdown-it@14.1.2': - resolution: {integrity: sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==} + "@types/markdown-it@14.1.2": + resolution: + { + integrity: sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==, + } - '@types/mdast@4.0.4': - resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} + "@types/mdast@4.0.4": + resolution: + { + integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==, + } - '@types/mdurl@2.0.0': - resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==} + "@types/mdurl@2.0.0": + resolution: + { + integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==, + } - '@types/unist@3.0.3': - resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + "@types/unist@3.0.3": + resolution: + { + integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==, + } - '@types/web-bluetooth@0.0.21': - resolution: {integrity: sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==} + "@types/web-bluetooth@0.0.21": + resolution: + { + integrity: sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==, + } - '@ungap/structured-clone@1.3.0': - resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} + "@ungap/structured-clone@1.3.0": + resolution: + { + integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==, + } - '@vitejs/plugin-vue@6.0.5': - resolution: {integrity: sha512-bL3AxKuQySfk1iGcBsQnoRVexTPJq0Z/ixFVM8OhVJAP6ZXXXLtM7NFKWhLl30Kg7uTBqIaPXbh+nuQCuBDedg==} - engines: {node: ^20.19.0 || >=22.12.0} + "@vitejs/plugin-vue@6.0.5": + resolution: + { + integrity: sha512-bL3AxKuQySfk1iGcBsQnoRVexTPJq0Z/ixFVM8OhVJAP6ZXXXLtM7NFKWhLl30Kg7uTBqIaPXbh+nuQCuBDedg==, + } + engines: { node: ^20.19.0 || >=22.12.0 } peerDependencies: vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 vue: ^3.2.25 - '@vue/compiler-core@3.5.30': - resolution: {integrity: sha512-s3DfdZkcu/qExZ+td75015ljzHc6vE+30cFMGRPROYjqkroYI5NV2X1yAMX9UeyBNWB9MxCfPcsjpLS11nzkkw==} + "@vue/compiler-core@3.5.30": + resolution: + { + integrity: sha512-s3DfdZkcu/qExZ+td75015ljzHc6vE+30cFMGRPROYjqkroYI5NV2X1yAMX9UeyBNWB9MxCfPcsjpLS11nzkkw==, + } - '@vue/compiler-dom@3.5.30': - resolution: {integrity: sha512-eCFYESUEVYHhiMuK4SQTldO3RYxyMR/UQL4KdGD1Yrkfdx4m/HYuZ9jSfPdA+nWJY34VWndiYdW/wZXyiPEB9g==} + "@vue/compiler-dom@3.5.30": + resolution: + { + integrity: sha512-eCFYESUEVYHhiMuK4SQTldO3RYxyMR/UQL4KdGD1Yrkfdx4m/HYuZ9jSfPdA+nWJY34VWndiYdW/wZXyiPEB9g==, + } - '@vue/compiler-sfc@3.5.30': - resolution: {integrity: sha512-LqmFPDn89dtU9vI3wHJnwaV6GfTRD87AjWpTWpyrdVOObVtjIuSeZr181z5C4PmVx/V3j2p+0f7edFKGRMpQ5A==} + "@vue/compiler-sfc@3.5.30": + resolution: + { + integrity: sha512-LqmFPDn89dtU9vI3wHJnwaV6GfTRD87AjWpTWpyrdVOObVtjIuSeZr181z5C4PmVx/V3j2p+0f7edFKGRMpQ5A==, + } - '@vue/compiler-ssr@3.5.30': - resolution: {integrity: sha512-NsYK6OMTnx109PSL2IAyf62JP6EUdk4Dmj6AkWcJGBvN0dQoMYtVekAmdqgTtWQgEJo+Okstbf/1p7qZr5H+bA==} + "@vue/compiler-ssr@3.5.30": + resolution: + { + integrity: sha512-NsYK6OMTnx109PSL2IAyf62JP6EUdk4Dmj6AkWcJGBvN0dQoMYtVekAmdqgTtWQgEJo+Okstbf/1p7qZr5H+bA==, + } - '@vue/devtools-api@8.1.0': - resolution: {integrity: sha512-O44X57jjkLKbLEc4OgL/6fEPOOanRJU8kYpCE8qfKlV96RQZcdzrcLI5mxMuVRUeXhHKIHGhCpHacyCk0HyO4w==} + "@vue/devtools-api@8.1.0": + resolution: + { + integrity: sha512-O44X57jjkLKbLEc4OgL/6fEPOOanRJU8kYpCE8qfKlV96RQZcdzrcLI5mxMuVRUeXhHKIHGhCpHacyCk0HyO4w==, + } - '@vue/devtools-kit@8.1.0': - resolution: {integrity: sha512-/NZlS4WtGIB54DA/z10gzk+n/V7zaqSzYZOVlg2CfdnpIKdB61bd7JDIMxf/zrtX41zod8E2/bbEBoW/d7x70Q==} + "@vue/devtools-kit@8.1.0": + resolution: + { + integrity: sha512-/NZlS4WtGIB54DA/z10gzk+n/V7zaqSzYZOVlg2CfdnpIKdB61bd7JDIMxf/zrtX41zod8E2/bbEBoW/d7x70Q==, + } - '@vue/devtools-shared@8.1.0': - resolution: {integrity: sha512-h8uCb4Qs8UT8VdTT5yjY6tOJ//qH7EpxToixR0xqejR55t5OdISIg7AJ7eBkhBs8iu1qG5gY3QQNN1DF1EelAA==} + "@vue/devtools-shared@8.1.0": + resolution: + { + integrity: sha512-h8uCb4Qs8UT8VdTT5yjY6tOJ//qH7EpxToixR0xqejR55t5OdISIg7AJ7eBkhBs8iu1qG5gY3QQNN1DF1EelAA==, + } - '@vue/reactivity@3.5.30': - resolution: {integrity: sha512-179YNgKATuwj9gB+66snskRDOitDiuOZqkYia7mHKJaidOMo/WJxHKF8DuGc4V4XbYTJANlfEKb0yxTQotnx4Q==} + "@vue/reactivity@3.5.30": + resolution: + { + integrity: sha512-179YNgKATuwj9gB+66snskRDOitDiuOZqkYia7mHKJaidOMo/WJxHKF8DuGc4V4XbYTJANlfEKb0yxTQotnx4Q==, + } - '@vue/runtime-core@3.5.30': - resolution: {integrity: sha512-e0Z+8PQsUTdwV8TtEsLzUM7SzC7lQwYKePydb7K2ZnmS6jjND+WJXkmmfh/swYzRyfP1EY3fpdesyYoymCzYfg==} + "@vue/runtime-core@3.5.30": + resolution: + { + integrity: sha512-e0Z+8PQsUTdwV8TtEsLzUM7SzC7lQwYKePydb7K2ZnmS6jjND+WJXkmmfh/swYzRyfP1EY3fpdesyYoymCzYfg==, + } - '@vue/runtime-dom@3.5.30': - resolution: {integrity: sha512-2UIGakjU4WSQ0T4iwDEW0W7vQj6n7AFn7taqZ9Cvm0Q/RA2FFOziLESrDL4GmtI1wV3jXg5nMoJSYO66egDUBw==} + "@vue/runtime-dom@3.5.30": + resolution: + { + integrity: sha512-2UIGakjU4WSQ0T4iwDEW0W7vQj6n7AFn7taqZ9Cvm0Q/RA2FFOziLESrDL4GmtI1wV3jXg5nMoJSYO66egDUBw==, + } - '@vue/server-renderer@3.5.30': - resolution: {integrity: sha512-v+R34icapydRwbZRD0sXwtHqrQJv38JuMB4JxbOxd8NEpGLny7cncMp53W9UH/zo4j8eDHjQ1dEJXwzFQknjtQ==} + "@vue/server-renderer@3.5.30": + resolution: + { + integrity: sha512-v+R34icapydRwbZRD0sXwtHqrQJv38JuMB4JxbOxd8NEpGLny7cncMp53W9UH/zo4j8eDHjQ1dEJXwzFQknjtQ==, + } peerDependencies: vue: 3.5.30 - '@vue/shared@3.5.30': - resolution: {integrity: sha512-YXgQ7JjaO18NeK2K9VTbDHaFy62WrObMa6XERNfNOkAhD1F1oDSf3ZJ7K6GqabZ0BvSDHajp8qfS5Sa2I9n8uQ==} + "@vue/shared@3.5.30": + resolution: + { + integrity: sha512-YXgQ7JjaO18NeK2K9VTbDHaFy62WrObMa6XERNfNOkAhD1F1oDSf3ZJ7K6GqabZ0BvSDHajp8qfS5Sa2I9n8uQ==, + } - '@vueuse/core@14.2.1': - resolution: {integrity: sha512-3vwDzV+GDUNpdegRY6kzpLm4Igptq+GA0QkJ3W61Iv27YWwW/ufSlOfgQIpN6FZRMG0mkaz4gglJRtq5SeJyIQ==} + "@vueuse/core@14.2.1": + resolution: + { + integrity: sha512-3vwDzV+GDUNpdegRY6kzpLm4Igptq+GA0QkJ3W61Iv27YWwW/ufSlOfgQIpN6FZRMG0mkaz4gglJRtq5SeJyIQ==, + } peerDependencies: vue: ^3.5.0 - '@vueuse/integrations@14.2.1': - resolution: {integrity: sha512-2LIUpBi/67PoXJGqSDQUF0pgQWpNHh7beiA+KG2AbybcNm+pTGWT6oPGlBgUoDWmYwfeQqM/uzOHqcILpKL7nA==} + "@vueuse/integrations@14.2.1": + resolution: + { + integrity: sha512-2LIUpBi/67PoXJGqSDQUF0pgQWpNHh7beiA+KG2AbybcNm+pTGWT6oPGlBgUoDWmYwfeQqM/uzOHqcILpKL7nA==, + } peerDependencies: async-validator: ^4 axios: ^1 @@ -504,102 +793,183 @@ packages: universal-cookie: optional: true - '@vueuse/metadata@14.2.1': - resolution: {integrity: sha512-1ButlVtj5Sb/HDtIy1HFr1VqCP4G6Ypqt5MAo0lCgjokrk2mvQKsK2uuy0vqu/Ks+sHfuHo0B9Y9jn9xKdjZsw==} + "@vueuse/metadata@14.2.1": + resolution: + { + integrity: sha512-1ButlVtj5Sb/HDtIy1HFr1VqCP4G6Ypqt5MAo0lCgjokrk2mvQKsK2uuy0vqu/Ks+sHfuHo0B9Y9jn9xKdjZsw==, + } - '@vueuse/shared@14.2.1': - resolution: {integrity: sha512-shTJncjV9JTI4oVNyF1FQonetYAiTBd+Qj7cY89SWbXSkx7gyhrgtEdF2ZAVWS1S3SHlaROO6F2IesJxQEkZBw==} + "@vueuse/shared@14.2.1": + resolution: + { + integrity: sha512-shTJncjV9JTI4oVNyF1FQonetYAiTBd+Qj7cY89SWbXSkx7gyhrgtEdF2ZAVWS1S3SHlaROO6F2IesJxQEkZBw==, + } peerDependencies: vue: ^3.5.0 ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==, + } + engines: { node: ">=8" } ansi-regex@6.2.2: - resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==, + } + engines: { node: ">=12" } ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==, + } + engines: { node: ">=8" } ansi-styles@6.2.3: - resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==, + } + engines: { node: ">=12" } argparse@1.0.10: - resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + resolution: + { + integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==, + } birpc@2.9.0: - resolution: {integrity: sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw==} + resolution: + { + integrity: sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw==, + } ccount@2.0.1: - resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + resolution: + { + integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==, + } character-entities-html4@2.1.0: - resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} + resolution: + { + integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==, + } character-entities-legacy@3.0.0: - resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} + resolution: + { + integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==, + } color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} + resolution: + { + integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==, + } + engines: { node: ">=7.0.0" } color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + resolution: + { + integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==, + } comma-separated-tokens@2.0.3: - resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + resolution: + { + integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==, + } cross-spawn@7.0.6: - resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} - engines: {node: '>= 8'} + resolution: + { + integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==, + } + engines: { node: ">= 8" } csstype@3.2.3: - resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + resolution: + { + integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==, + } dequal@2.0.3: - resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==, + } + engines: { node: ">=6" } devlop@1.1.0: - resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + resolution: + { + integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==, + } eastasianwidth@0.2.0: - resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + resolution: + { + integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==, + } emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + resolution: + { + integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==, + } emoji-regex@9.2.2: - resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + resolution: + { + integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==, + } entities@7.0.1: - resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==} - engines: {node: '>=0.12'} + resolution: + { + integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==, + } + engines: { node: ">=0.12" } esbuild@0.27.4: - resolution: {integrity: sha512-Rq4vbHnYkK5fws5NF7MYTU68FPRE1ajX7heQ/8QXXWqNgqqJ/GkmmyxIzUnf2Sr/bakf8l54716CcMGHYhMrrQ==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-Rq4vbHnYkK5fws5NF7MYTU68FPRE1ajX7heQ/8QXXWqNgqqJ/GkmmyxIzUnf2Sr/bakf8l54716CcMGHYhMrrQ==, + } + engines: { node: ">=18" } hasBin: true esprima@4.0.1: - resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==, + } + engines: { node: ">=4" } hasBin: true estree-walker@2.0.2: - resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + resolution: + { + integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==, + } extend-shallow@2.0.1: - resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==, + } + engines: { node: ">=0.10.0" } fdir@6.5.0: - resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} - engines: {node: '>=12.0.0'} + resolution: + { + integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==, + } + engines: { node: ">=12.0.0" } peerDependencies: picomatch: ^3 || ^4 peerDependenciesMeta: @@ -607,258 +977,463 @@ packages: optional: true focus-trap@7.8.0: - resolution: {integrity: sha512-/yNdlIkpWbM0ptxno3ONTuf+2g318kh2ez3KSeZN5dZ8YC6AAmgeWz+GasYYiBJPFaYcSAPeu4GfhUaChzIJXA==} + resolution: + { + integrity: sha512-/yNdlIkpWbM0ptxno3ONTuf+2g318kh2ez3KSeZN5dZ8YC6AAmgeWz+GasYYiBJPFaYcSAPeu4GfhUaChzIJXA==, + } foreground-child@3.3.1: - resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} - engines: {node: '>=14'} + resolution: + { + integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==, + } + engines: { node: ">=14" } fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + resolution: + { + integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==, + } + engines: { node: ^8.16.0 || ^10.6.0 || >=11.0.0 } os: [darwin] glob@11.1.0: - resolution: {integrity: sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==} - engines: {node: 20 || >=22} + resolution: + { + integrity: sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==, + } + engines: { node: 20 || >=22 } + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me hasBin: true gray-matter@4.0.3: - resolution: {integrity: sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==} - engines: {node: '>=6.0'} + resolution: + { + integrity: sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==, + } + engines: { node: ">=6.0" } hast-util-to-html@9.0.5: - resolution: {integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==} + resolution: + { + integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==, + } hast-util-whitespace@3.0.0: - resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} + resolution: + { + integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==, + } hookable@5.5.3: - resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==} + resolution: + { + integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==, + } html-void-elements@3.0.0: - resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} + resolution: + { + integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==, + } is-extendable@0.1.1: - resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==, + } + engines: { node: ">=0.10.0" } is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==, + } + engines: { node: ">=8" } isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + resolution: + { + integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==, + } jackspeak@4.1.1: - resolution: {integrity: sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==} - engines: {node: 20 || >=22} + resolution: + { + integrity: sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==, + } + engines: { node: 20 || >=22 } js-yaml@3.14.2: - resolution: {integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==} + resolution: + { + integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==, + } hasBin: true kind-of@6.0.3: - resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==, + } + engines: { node: ">=0.10.0" } lru-cache@11.2.4: - resolution: {integrity: sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==} - engines: {node: 20 || >=22} + resolution: + { + integrity: sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==, + } + engines: { node: 20 || >=22 } magic-string@0.30.21: - resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + resolution: + { + integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==, + } mark.js@8.11.1: - resolution: {integrity: sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==} + resolution: + { + integrity: sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==, + } mdast-util-to-hast@13.2.1: - resolution: {integrity: sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==} + resolution: + { + integrity: sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==, + } micromark-util-character@2.1.1: - resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} + resolution: + { + integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==, + } micromark-util-encode@2.0.1: - resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} + resolution: + { + integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==, + } micromark-util-sanitize-uri@2.0.1: - resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} + resolution: + { + integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==, + } micromark-util-symbol@2.0.1: - resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} + resolution: + { + integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==, + } micromark-util-types@2.0.2: - resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} + resolution: + { + integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==, + } minimatch@10.1.1: - resolution: {integrity: sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==} - engines: {node: 20 || >=22} + resolution: + { + integrity: sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==, + } + engines: { node: 20 || >=22 } minipass@7.1.2: - resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} - engines: {node: '>=16 || 14 >=14.17'} + resolution: + { + integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==, + } + engines: { node: ">=16 || 14 >=14.17" } minisearch@7.2.0: - resolution: {integrity: sha512-dqT2XBYUOZOiC5t2HRnwADjhNS2cecp9u+TJRiJ1Qp/f5qjkeT5APcGPjHw+bz89Ms8Jp+cG4AlE+QZ/QnDglg==} + resolution: + { + integrity: sha512-dqT2XBYUOZOiC5t2HRnwADjhNS2cecp9u+TJRiJ1Qp/f5qjkeT5APcGPjHw+bz89Ms8Jp+cG4AlE+QZ/QnDglg==, + } nanoid@3.3.11: - resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + resolution: + { + integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==, + } + engines: { node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1 } hasBin: true oniguruma-parser@0.12.1: - resolution: {integrity: sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w==} + resolution: + { + integrity: sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w==, + } oniguruma-to-es@4.3.5: - resolution: {integrity: sha512-Zjygswjpsewa0NLTsiizVuMQZbp0MDyM6lIt66OxsF21npUDlzpHi1Mgb/qhQdkb+dWFTzJmFbEWdvZgRho8eQ==} + resolution: + { + integrity: sha512-Zjygswjpsewa0NLTsiizVuMQZbp0MDyM6lIt66OxsF21npUDlzpHi1Mgb/qhQdkb+dWFTzJmFbEWdvZgRho8eQ==, + } package-json-from-dist@1.0.1: - resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + resolution: + { + integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==, + } path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==, + } + engines: { node: ">=8" } path-scurry@2.0.1: - resolution: {integrity: sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==} - engines: {node: 20 || >=22} + resolution: + { + integrity: sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==, + } + engines: { node: 20 || >=22 } perfect-debounce@2.1.0: - resolution: {integrity: sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g==} + resolution: + { + integrity: sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g==, + } picocolors@1.1.1: - resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + resolution: + { + integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==, + } picomatch@4.0.3: - resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==, + } + engines: { node: ">=12" } postcss@8.5.8: - resolution: {integrity: sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==} - engines: {node: ^10 || ^12 || >=14} + resolution: + { + integrity: sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==, + } + engines: { node: ^10 || ^12 || >=14 } property-information@7.1.0: - resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==} + resolution: + { + integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==, + } qsu@1.10.4: - resolution: {integrity: sha512-v5RhwvHMkDdbXEaAxQh5re8q7DiG6EE70+CNwYVA6wZsa4gUrpur+D8lIO3PrzeCj3azc/S79X5v3BH8ILfr9A==} - engines: {node: '>=18.0.0'} + resolution: + { + integrity: sha512-v5RhwvHMkDdbXEaAxQh5re8q7DiG6EE70+CNwYVA6wZsa4gUrpur+D8lIO3PrzeCj3azc/S79X5v3BH8ILfr9A==, + } + engines: { node: ">=18.0.0" } regex-recursion@6.0.2: - resolution: {integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==} + resolution: + { + integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==, + } regex-utilities@2.3.0: - resolution: {integrity: sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==} + resolution: + { + integrity: sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==, + } regex@6.1.0: - resolution: {integrity: sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==} + resolution: + { + integrity: sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==, + } rollup@4.59.0: - resolution: {integrity: sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==} - engines: {node: '>=18.0.0', npm: '>=8.0.0'} + resolution: + { + integrity: sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==, + } + engines: { node: ">=18.0.0", npm: ">=8.0.0" } hasBin: true section-matter@1.0.0: - resolution: {integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==, + } + engines: { node: ">=4" } shebang-command@2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==, + } + engines: { node: ">=8" } shebang-regex@3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==, + } + engines: { node: ">=8" } shiki@3.23.0: - resolution: {integrity: sha512-55Dj73uq9ZXL5zyeRPzHQsK7Nbyt6Y10k5s7OjuFZGMhpp4r/rsLBH0o/0fstIzX1Lep9VxefWljK/SKCzygIA==} + resolution: + { + integrity: sha512-55Dj73uq9ZXL5zyeRPzHQsK7Nbyt6Y10k5s7OjuFZGMhpp4r/rsLBH0o/0fstIzX1Lep9VxefWljK/SKCzygIA==, + } signal-exit@4.1.0: - resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} - engines: {node: '>=14'} + resolution: + { + integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==, + } + engines: { node: ">=14" } source-map-js@1.2.1: - resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==, + } + engines: { node: ">=0.10.0" } space-separated-tokens@2.0.2: - resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + resolution: + { + integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==, + } sprintf-js@1.0.3: - resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + resolution: + { + integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==, + } string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==, + } + engines: { node: ">=8" } string-width@5.1.2: - resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==, + } + engines: { node: ">=12" } stringify-entities@4.0.4: - resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} + resolution: + { + integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==, + } strip-ansi@6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==, + } + engines: { node: ">=8" } strip-ansi@7.1.2: - resolution: {integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==, + } + engines: { node: ">=12" } strip-bom-string@1.0.0: - resolution: {integrity: sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==, + } + engines: { node: ">=0.10.0" } tabbable@6.4.0: - resolution: {integrity: sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg==} + resolution: + { + integrity: sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg==, + } tinyglobby@0.2.15: - resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} - engines: {node: '>=12.0.0'} + resolution: + { + integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==, + } + engines: { node: ">=12.0.0" } trim-lines@3.0.1: - resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} + resolution: + { + integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==, + } unist-util-is@6.0.1: - resolution: {integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==} + resolution: + { + integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==, + } unist-util-position@5.0.0: - resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} + resolution: + { + integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==, + } unist-util-stringify-position@4.0.0: - resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + resolution: + { + integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==, + } unist-util-visit-parents@6.0.2: - resolution: {integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==} + resolution: + { + integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==, + } unist-util-visit@5.1.0: - resolution: {integrity: sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==} + resolution: + { + integrity: sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==, + } vfile-message@4.0.3: - resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} + resolution: + { + integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==, + } vfile@6.0.3: - resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + resolution: + { + integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==, + } vite@7.3.1: - resolution: {integrity: sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==} - engines: {node: ^20.19.0 || >=22.12.0} + resolution: + { + integrity: sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==, + } + engines: { node: ^20.19.0 || >=22.12.0 } hasBin: true peerDependencies: - '@types/node': ^20.19.0 || >=22.12.0 - jiti: '>=1.21.0' + "@types/node": ^20.19.0 || >=22.12.0 + jiti: ">=1.21.0" less: ^4.0.0 lightningcss: ^1.21.0 sass: ^1.70.0 sass-embedded: ^1.70.0 - stylus: '>=0.54.8' + stylus: ">=0.54.8" sugarss: ^5.0.0 terser: ^5.16.0 tsx: ^4.8.1 yaml: ^2.4.2 peerDependenciesMeta: - '@types/node': + "@types/node": optional: true jiti: optional: true @@ -882,15 +1457,21 @@ packages: optional: true vitepress-sidebar@1.33.1: - resolution: {integrity: sha512-wPUbXezGakVldawixeRW5tKQTLKoMj2t4nWoThKfCltBM/9a38IE+wCXmmRNW22ZKC32SD/X/sG6NyCTK8QBRg==} - engines: {node: '>=18.0.0'} + resolution: + { + integrity: sha512-wPUbXezGakVldawixeRW5tKQTLKoMj2t4nWoThKfCltBM/9a38IE+wCXmmRNW22ZKC32SD/X/sG6NyCTK8QBRg==, + } + engines: { node: ">=18.0.0" } vitepress@2.0.0-alpha.16: - resolution: {integrity: sha512-w1nwsefDVIsje7BZr2tsKxkZutDGjG0YoQ2yxO7+a9tvYVqfljYbwj5LMYkPy8Tb7YbPwa22HtIhk62jbrvuEQ==} + resolution: + { + integrity: sha512-w1nwsefDVIsje7BZr2tsKxkZutDGjG0YoQ2yxO7+a9tvYVqfljYbwj5LMYkPy8Tb7YbPwa22HtIhk62jbrvuEQ==, + } hasBin: true peerDependencies: markdown-it-mathjax3: ^4 - oxc-minify: '*' + oxc-minify: "*" postcss: ^8 peerDependenciesMeta: markdown-it-mathjax3: @@ -901,141 +1482,155 @@ packages: optional: true vue@3.5.30: - resolution: {integrity: sha512-hTHLc6VNZyzzEH/l7PFGjpcTvUgiaPK5mdLkbjrTeWSRcEfxFrv56g/XckIYlE9ckuobsdwqd5mk2g1sBkMewg==} + resolution: + { + integrity: sha512-hTHLc6VNZyzzEH/l7PFGjpcTvUgiaPK5mdLkbjrTeWSRcEfxFrv56g/XckIYlE9ckuobsdwqd5mk2g1sBkMewg==, + } peerDependencies: - typescript: '*' + typescript: "*" peerDependenciesMeta: typescript: optional: true which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} + resolution: + { + integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==, + } + engines: { node: ">= 8" } hasBin: true wrap-ansi@7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==, + } + engines: { node: ">=10" } wrap-ansi@8.1.0: - resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==, + } + engines: { node: ">=12" } zwitch@2.0.4: - resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + resolution: + { + integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==, + } snapshots: + "@babel/helper-string-parser@7.27.1": {} - '@babel/helper-string-parser@7.27.1': {} + "@babel/helper-validator-identifier@7.28.5": {} - '@babel/helper-validator-identifier@7.28.5': {} - - '@babel/parser@7.29.0': + "@babel/parser@7.29.0": dependencies: - '@babel/types': 7.29.0 + "@babel/types": 7.29.0 - '@babel/types@7.29.0': + "@babel/types@7.29.0": dependencies: - '@babel/helper-string-parser': 7.27.1 - '@babel/helper-validator-identifier': 7.28.5 + "@babel/helper-string-parser": 7.27.1 + "@babel/helper-validator-identifier": 7.28.5 - '@docsearch/css@4.6.0': {} + "@docsearch/css@4.6.0": {} - '@docsearch/js@4.6.0': {} + "@docsearch/js@4.6.0": {} - '@docsearch/sidepanel-js@4.6.0': {} + "@docsearch/sidepanel-js@4.6.0": {} - '@esbuild/aix-ppc64@0.27.4': + "@esbuild/aix-ppc64@0.27.4": optional: true - '@esbuild/android-arm64@0.27.4': + "@esbuild/android-arm64@0.27.4": optional: true - '@esbuild/android-arm@0.27.4': + "@esbuild/android-arm@0.27.4": optional: true - '@esbuild/android-x64@0.27.4': + "@esbuild/android-x64@0.27.4": optional: true - '@esbuild/darwin-arm64@0.27.4': + "@esbuild/darwin-arm64@0.27.4": optional: true - '@esbuild/darwin-x64@0.27.4': + "@esbuild/darwin-x64@0.27.4": optional: true - '@esbuild/freebsd-arm64@0.27.4': + "@esbuild/freebsd-arm64@0.27.4": optional: true - '@esbuild/freebsd-x64@0.27.4': + "@esbuild/freebsd-x64@0.27.4": optional: true - '@esbuild/linux-arm64@0.27.4': + "@esbuild/linux-arm64@0.27.4": optional: true - '@esbuild/linux-arm@0.27.4': + "@esbuild/linux-arm@0.27.4": optional: true - '@esbuild/linux-ia32@0.27.4': + "@esbuild/linux-ia32@0.27.4": optional: true - '@esbuild/linux-loong64@0.27.4': + "@esbuild/linux-loong64@0.27.4": optional: true - '@esbuild/linux-mips64el@0.27.4': + "@esbuild/linux-mips64el@0.27.4": optional: true - '@esbuild/linux-ppc64@0.27.4': + "@esbuild/linux-ppc64@0.27.4": optional: true - '@esbuild/linux-riscv64@0.27.4': + "@esbuild/linux-riscv64@0.27.4": optional: true - '@esbuild/linux-s390x@0.27.4': + "@esbuild/linux-s390x@0.27.4": optional: true - '@esbuild/linux-x64@0.27.4': + "@esbuild/linux-x64@0.27.4": optional: true - '@esbuild/netbsd-arm64@0.27.4': + "@esbuild/netbsd-arm64@0.27.4": optional: true - '@esbuild/netbsd-x64@0.27.4': + "@esbuild/netbsd-x64@0.27.4": optional: true - '@esbuild/openbsd-arm64@0.27.4': + "@esbuild/openbsd-arm64@0.27.4": optional: true - '@esbuild/openbsd-x64@0.27.4': + "@esbuild/openbsd-x64@0.27.4": optional: true - '@esbuild/openharmony-arm64@0.27.4': + "@esbuild/openharmony-arm64@0.27.4": optional: true - '@esbuild/sunos-x64@0.27.4': + "@esbuild/sunos-x64@0.27.4": optional: true - '@esbuild/win32-arm64@0.27.4': + "@esbuild/win32-arm64@0.27.4": optional: true - '@esbuild/win32-ia32@0.27.4': + "@esbuild/win32-ia32@0.27.4": optional: true - '@esbuild/win32-x64@0.27.4': + "@esbuild/win32-x64@0.27.4": optional: true - '@iconify-json/simple-icons@1.2.74': + "@iconify-json/simple-icons@1.2.74": dependencies: - '@iconify/types': 2.0.0 + "@iconify/types": 2.0.0 - '@iconify/types@2.0.0': {} + "@iconify/types@2.0.0": {} - '@isaacs/balanced-match@4.0.1': {} + "@isaacs/balanced-match@4.0.1": {} - '@isaacs/brace-expansion@5.0.0': + "@isaacs/brace-expansion@5.0.0": dependencies: - '@isaacs/balanced-match': 4.0.1 + "@isaacs/balanced-match": 4.0.1 - '@isaacs/cliui@8.0.2': + "@isaacs/cliui@8.0.2": dependencies: string-width: 5.1.2 string-width-cjs: string-width@4.2.3 @@ -1044,239 +1639,239 @@ snapshots: wrap-ansi: 8.1.0 wrap-ansi-cjs: wrap-ansi@7.0.0 - '@jridgewell/sourcemap-codec@1.5.5': {} + "@jridgewell/sourcemap-codec@1.5.5": {} - '@rolldown/pluginutils@1.0.0-rc.2': {} + "@rolldown/pluginutils@1.0.0-rc.2": {} - '@rollup/rollup-android-arm-eabi@4.59.0': + "@rollup/rollup-android-arm-eabi@4.59.0": optional: true - '@rollup/rollup-android-arm64@4.59.0': + "@rollup/rollup-android-arm64@4.59.0": optional: true - '@rollup/rollup-darwin-arm64@4.59.0': + "@rollup/rollup-darwin-arm64@4.59.0": optional: true - '@rollup/rollup-darwin-x64@4.59.0': + "@rollup/rollup-darwin-x64@4.59.0": optional: true - '@rollup/rollup-freebsd-arm64@4.59.0': + "@rollup/rollup-freebsd-arm64@4.59.0": optional: true - '@rollup/rollup-freebsd-x64@4.59.0': + "@rollup/rollup-freebsd-x64@4.59.0": optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.59.0': + "@rollup/rollup-linux-arm-gnueabihf@4.59.0": optional: true - '@rollup/rollup-linux-arm-musleabihf@4.59.0': + "@rollup/rollup-linux-arm-musleabihf@4.59.0": optional: true - '@rollup/rollup-linux-arm64-gnu@4.59.0': + "@rollup/rollup-linux-arm64-gnu@4.59.0": optional: true - '@rollup/rollup-linux-arm64-musl@4.59.0': + "@rollup/rollup-linux-arm64-musl@4.59.0": optional: true - '@rollup/rollup-linux-loong64-gnu@4.59.0': + "@rollup/rollup-linux-loong64-gnu@4.59.0": optional: true - '@rollup/rollup-linux-loong64-musl@4.59.0': + "@rollup/rollup-linux-loong64-musl@4.59.0": optional: true - '@rollup/rollup-linux-ppc64-gnu@4.59.0': + "@rollup/rollup-linux-ppc64-gnu@4.59.0": optional: true - '@rollup/rollup-linux-ppc64-musl@4.59.0': + "@rollup/rollup-linux-ppc64-musl@4.59.0": optional: true - '@rollup/rollup-linux-riscv64-gnu@4.59.0': + "@rollup/rollup-linux-riscv64-gnu@4.59.0": optional: true - '@rollup/rollup-linux-riscv64-musl@4.59.0': + "@rollup/rollup-linux-riscv64-musl@4.59.0": optional: true - '@rollup/rollup-linux-s390x-gnu@4.59.0': + "@rollup/rollup-linux-s390x-gnu@4.59.0": optional: true - '@rollup/rollup-linux-x64-gnu@4.59.0': + "@rollup/rollup-linux-x64-gnu@4.59.0": optional: true - '@rollup/rollup-linux-x64-musl@4.59.0': + "@rollup/rollup-linux-x64-musl@4.59.0": optional: true - '@rollup/rollup-openbsd-x64@4.59.0': + "@rollup/rollup-openbsd-x64@4.59.0": optional: true - '@rollup/rollup-openharmony-arm64@4.59.0': + "@rollup/rollup-openharmony-arm64@4.59.0": optional: true - '@rollup/rollup-win32-arm64-msvc@4.59.0': + "@rollup/rollup-win32-arm64-msvc@4.59.0": optional: true - '@rollup/rollup-win32-ia32-msvc@4.59.0': + "@rollup/rollup-win32-ia32-msvc@4.59.0": optional: true - '@rollup/rollup-win32-x64-gnu@4.59.0': + "@rollup/rollup-win32-x64-gnu@4.59.0": optional: true - '@rollup/rollup-win32-x64-msvc@4.59.0': + "@rollup/rollup-win32-x64-msvc@4.59.0": optional: true - '@shikijs/core@3.23.0': + "@shikijs/core@3.23.0": dependencies: - '@shikijs/types': 3.23.0 - '@shikijs/vscode-textmate': 10.0.2 - '@types/hast': 3.0.4 + "@shikijs/types": 3.23.0 + "@shikijs/vscode-textmate": 10.0.2 + "@types/hast": 3.0.4 hast-util-to-html: 9.0.5 - '@shikijs/engine-javascript@3.23.0': + "@shikijs/engine-javascript@3.23.0": dependencies: - '@shikijs/types': 3.23.0 - '@shikijs/vscode-textmate': 10.0.2 + "@shikijs/types": 3.23.0 + "@shikijs/vscode-textmate": 10.0.2 oniguruma-to-es: 4.3.5 - '@shikijs/engine-oniguruma@3.23.0': + "@shikijs/engine-oniguruma@3.23.0": dependencies: - '@shikijs/types': 3.23.0 - '@shikijs/vscode-textmate': 10.0.2 + "@shikijs/types": 3.23.0 + "@shikijs/vscode-textmate": 10.0.2 - '@shikijs/langs@3.23.0': + "@shikijs/langs@3.23.0": dependencies: - '@shikijs/types': 3.23.0 + "@shikijs/types": 3.23.0 - '@shikijs/themes@3.23.0': + "@shikijs/themes@3.23.0": dependencies: - '@shikijs/types': 3.23.0 + "@shikijs/types": 3.23.0 - '@shikijs/transformers@3.23.0': + "@shikijs/transformers@3.23.0": dependencies: - '@shikijs/core': 3.23.0 - '@shikijs/types': 3.23.0 + "@shikijs/core": 3.23.0 + "@shikijs/types": 3.23.0 - '@shikijs/types@3.23.0': + "@shikijs/types@3.23.0": dependencies: - '@shikijs/vscode-textmate': 10.0.2 - '@types/hast': 3.0.4 + "@shikijs/vscode-textmate": 10.0.2 + "@types/hast": 3.0.4 - '@shikijs/vscode-textmate@10.0.2': {} + "@shikijs/vscode-textmate@10.0.2": {} - '@types/estree@1.0.8': {} + "@types/estree@1.0.8": {} - '@types/hast@3.0.4': + "@types/hast@3.0.4": dependencies: - '@types/unist': 3.0.3 + "@types/unist": 3.0.3 - '@types/linkify-it@5.0.0': {} + "@types/linkify-it@5.0.0": {} - '@types/markdown-it@14.1.2': + "@types/markdown-it@14.1.2": dependencies: - '@types/linkify-it': 5.0.0 - '@types/mdurl': 2.0.0 + "@types/linkify-it": 5.0.0 + "@types/mdurl": 2.0.0 - '@types/mdast@4.0.4': + "@types/mdast@4.0.4": dependencies: - '@types/unist': 3.0.3 + "@types/unist": 3.0.3 - '@types/mdurl@2.0.0': {} + "@types/mdurl@2.0.0": {} - '@types/unist@3.0.3': {} + "@types/unist@3.0.3": {} - '@types/web-bluetooth@0.0.21': {} + "@types/web-bluetooth@0.0.21": {} - '@ungap/structured-clone@1.3.0': {} + "@ungap/structured-clone@1.3.0": {} - '@vitejs/plugin-vue@6.0.5(vite@7.3.1)(vue@3.5.30)': + "@vitejs/plugin-vue@6.0.5(vite@7.3.1)(vue@3.5.30)": dependencies: - '@rolldown/pluginutils': 1.0.0-rc.2 + "@rolldown/pluginutils": 1.0.0-rc.2 vite: 7.3.1 vue: 3.5.30 - '@vue/compiler-core@3.5.30': + "@vue/compiler-core@3.5.30": dependencies: - '@babel/parser': 7.29.0 - '@vue/shared': 3.5.30 + "@babel/parser": 7.29.0 + "@vue/shared": 3.5.30 entities: 7.0.1 estree-walker: 2.0.2 source-map-js: 1.2.1 - '@vue/compiler-dom@3.5.30': + "@vue/compiler-dom@3.5.30": dependencies: - '@vue/compiler-core': 3.5.30 - '@vue/shared': 3.5.30 + "@vue/compiler-core": 3.5.30 + "@vue/shared": 3.5.30 - '@vue/compiler-sfc@3.5.30': + "@vue/compiler-sfc@3.5.30": dependencies: - '@babel/parser': 7.29.0 - '@vue/compiler-core': 3.5.30 - '@vue/compiler-dom': 3.5.30 - '@vue/compiler-ssr': 3.5.30 - '@vue/shared': 3.5.30 + "@babel/parser": 7.29.0 + "@vue/compiler-core": 3.5.30 + "@vue/compiler-dom": 3.5.30 + "@vue/compiler-ssr": 3.5.30 + "@vue/shared": 3.5.30 estree-walker: 2.0.2 magic-string: 0.30.21 postcss: 8.5.8 source-map-js: 1.2.1 - '@vue/compiler-ssr@3.5.30': + "@vue/compiler-ssr@3.5.30": dependencies: - '@vue/compiler-dom': 3.5.30 - '@vue/shared': 3.5.30 + "@vue/compiler-dom": 3.5.30 + "@vue/shared": 3.5.30 - '@vue/devtools-api@8.1.0': + "@vue/devtools-api@8.1.0": dependencies: - '@vue/devtools-kit': 8.1.0 + "@vue/devtools-kit": 8.1.0 - '@vue/devtools-kit@8.1.0': + "@vue/devtools-kit@8.1.0": dependencies: - '@vue/devtools-shared': 8.1.0 + "@vue/devtools-shared": 8.1.0 birpc: 2.9.0 hookable: 5.5.3 perfect-debounce: 2.1.0 - '@vue/devtools-shared@8.1.0': {} + "@vue/devtools-shared@8.1.0": {} - '@vue/reactivity@3.5.30': + "@vue/reactivity@3.5.30": dependencies: - '@vue/shared': 3.5.30 + "@vue/shared": 3.5.30 - '@vue/runtime-core@3.5.30': + "@vue/runtime-core@3.5.30": dependencies: - '@vue/reactivity': 3.5.30 - '@vue/shared': 3.5.30 + "@vue/reactivity": 3.5.30 + "@vue/shared": 3.5.30 - '@vue/runtime-dom@3.5.30': + "@vue/runtime-dom@3.5.30": dependencies: - '@vue/reactivity': 3.5.30 - '@vue/runtime-core': 3.5.30 - '@vue/shared': 3.5.30 + "@vue/reactivity": 3.5.30 + "@vue/runtime-core": 3.5.30 + "@vue/shared": 3.5.30 csstype: 3.2.3 - '@vue/server-renderer@3.5.30(vue@3.5.30)': + "@vue/server-renderer@3.5.30(vue@3.5.30)": dependencies: - '@vue/compiler-ssr': 3.5.30 - '@vue/shared': 3.5.30 + "@vue/compiler-ssr": 3.5.30 + "@vue/shared": 3.5.30 vue: 3.5.30 - '@vue/shared@3.5.30': {} + "@vue/shared@3.5.30": {} - '@vueuse/core@14.2.1(vue@3.5.30)': + "@vueuse/core@14.2.1(vue@3.5.30)": dependencies: - '@types/web-bluetooth': 0.0.21 - '@vueuse/metadata': 14.2.1 - '@vueuse/shared': 14.2.1(vue@3.5.30) + "@types/web-bluetooth": 0.0.21 + "@vueuse/metadata": 14.2.1 + "@vueuse/shared": 14.2.1(vue@3.5.30) vue: 3.5.30 - '@vueuse/integrations@14.2.1(focus-trap@7.8.0)(vue@3.5.30)': + "@vueuse/integrations@14.2.1(focus-trap@7.8.0)(vue@3.5.30)": dependencies: - '@vueuse/core': 14.2.1(vue@3.5.30) - '@vueuse/shared': 14.2.1(vue@3.5.30) + "@vueuse/core": 14.2.1(vue@3.5.30) + "@vueuse/shared": 14.2.1(vue@3.5.30) vue: 3.5.30 optionalDependencies: focus-trap: 7.8.0 - '@vueuse/metadata@14.2.1': {} + "@vueuse/metadata@14.2.1": {} - '@vueuse/shared@14.2.1(vue@3.5.30)': + "@vueuse/shared@14.2.1(vue@3.5.30)": dependencies: vue: 3.5.30 @@ -1334,32 +1929,32 @@ snapshots: esbuild@0.27.4: optionalDependencies: - '@esbuild/aix-ppc64': 0.27.4 - '@esbuild/android-arm': 0.27.4 - '@esbuild/android-arm64': 0.27.4 - '@esbuild/android-x64': 0.27.4 - '@esbuild/darwin-arm64': 0.27.4 - '@esbuild/darwin-x64': 0.27.4 - '@esbuild/freebsd-arm64': 0.27.4 - '@esbuild/freebsd-x64': 0.27.4 - '@esbuild/linux-arm': 0.27.4 - '@esbuild/linux-arm64': 0.27.4 - '@esbuild/linux-ia32': 0.27.4 - '@esbuild/linux-loong64': 0.27.4 - '@esbuild/linux-mips64el': 0.27.4 - '@esbuild/linux-ppc64': 0.27.4 - '@esbuild/linux-riscv64': 0.27.4 - '@esbuild/linux-s390x': 0.27.4 - '@esbuild/linux-x64': 0.27.4 - '@esbuild/netbsd-arm64': 0.27.4 - '@esbuild/netbsd-x64': 0.27.4 - '@esbuild/openbsd-arm64': 0.27.4 - '@esbuild/openbsd-x64': 0.27.4 - '@esbuild/openharmony-arm64': 0.27.4 - '@esbuild/sunos-x64': 0.27.4 - '@esbuild/win32-arm64': 0.27.4 - '@esbuild/win32-ia32': 0.27.4 - '@esbuild/win32-x64': 0.27.4 + "@esbuild/aix-ppc64": 0.27.4 + "@esbuild/android-arm": 0.27.4 + "@esbuild/android-arm64": 0.27.4 + "@esbuild/android-x64": 0.27.4 + "@esbuild/darwin-arm64": 0.27.4 + "@esbuild/darwin-x64": 0.27.4 + "@esbuild/freebsd-arm64": 0.27.4 + "@esbuild/freebsd-x64": 0.27.4 + "@esbuild/linux-arm": 0.27.4 + "@esbuild/linux-arm64": 0.27.4 + "@esbuild/linux-ia32": 0.27.4 + "@esbuild/linux-loong64": 0.27.4 + "@esbuild/linux-mips64el": 0.27.4 + "@esbuild/linux-ppc64": 0.27.4 + "@esbuild/linux-riscv64": 0.27.4 + "@esbuild/linux-s390x": 0.27.4 + "@esbuild/linux-x64": 0.27.4 + "@esbuild/netbsd-arm64": 0.27.4 + "@esbuild/netbsd-x64": 0.27.4 + "@esbuild/openbsd-arm64": 0.27.4 + "@esbuild/openbsd-x64": 0.27.4 + "@esbuild/openharmony-arm64": 0.27.4 + "@esbuild/sunos-x64": 0.27.4 + "@esbuild/win32-arm64": 0.27.4 + "@esbuild/win32-ia32": 0.27.4 + "@esbuild/win32-x64": 0.27.4 esprima@4.0.1: {} @@ -1403,8 +1998,8 @@ snapshots: hast-util-to-html@9.0.5: dependencies: - '@types/hast': 3.0.4 - '@types/unist': 3.0.3 + "@types/hast": 3.0.4 + "@types/unist": 3.0.3 ccount: 2.0.1 comma-separated-tokens: 2.0.3 hast-util-whitespace: 3.0.0 @@ -1417,7 +2012,7 @@ snapshots: hast-util-whitespace@3.0.0: dependencies: - '@types/hast': 3.0.4 + "@types/hast": 3.0.4 hookable@5.5.3: {} @@ -1431,7 +2026,7 @@ snapshots: jackspeak@4.1.1: dependencies: - '@isaacs/cliui': 8.0.2 + "@isaacs/cliui": 8.0.2 js-yaml@3.14.2: dependencies: @@ -1444,15 +2039,15 @@ snapshots: magic-string@0.30.21: dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 + "@jridgewell/sourcemap-codec": 1.5.5 mark.js@8.11.1: {} mdast-util-to-hast@13.2.1: dependencies: - '@types/hast': 3.0.4 - '@types/mdast': 4.0.4 - '@ungap/structured-clone': 1.3.0 + "@types/hast": 3.0.4 + "@types/mdast": 4.0.4 + "@ungap/structured-clone": 1.3.0 devlop: 1.1.0 micromark-util-sanitize-uri: 2.0.1 trim-lines: 3.0.1 @@ -1479,7 +2074,7 @@ snapshots: minimatch@10.1.1: dependencies: - '@isaacs/brace-expansion': 5.0.0 + "@isaacs/brace-expansion": 5.0.0 minipass@7.1.2: {} @@ -1532,33 +2127,33 @@ snapshots: rollup@4.59.0: dependencies: - '@types/estree': 1.0.8 + "@types/estree": 1.0.8 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.59.0 - '@rollup/rollup-android-arm64': 4.59.0 - '@rollup/rollup-darwin-arm64': 4.59.0 - '@rollup/rollup-darwin-x64': 4.59.0 - '@rollup/rollup-freebsd-arm64': 4.59.0 - '@rollup/rollup-freebsd-x64': 4.59.0 - '@rollup/rollup-linux-arm-gnueabihf': 4.59.0 - '@rollup/rollup-linux-arm-musleabihf': 4.59.0 - '@rollup/rollup-linux-arm64-gnu': 4.59.0 - '@rollup/rollup-linux-arm64-musl': 4.59.0 - '@rollup/rollup-linux-loong64-gnu': 4.59.0 - '@rollup/rollup-linux-loong64-musl': 4.59.0 - '@rollup/rollup-linux-ppc64-gnu': 4.59.0 - '@rollup/rollup-linux-ppc64-musl': 4.59.0 - '@rollup/rollup-linux-riscv64-gnu': 4.59.0 - '@rollup/rollup-linux-riscv64-musl': 4.59.0 - '@rollup/rollup-linux-s390x-gnu': 4.59.0 - '@rollup/rollup-linux-x64-gnu': 4.59.0 - '@rollup/rollup-linux-x64-musl': 4.59.0 - '@rollup/rollup-openbsd-x64': 4.59.0 - '@rollup/rollup-openharmony-arm64': 4.59.0 - '@rollup/rollup-win32-arm64-msvc': 4.59.0 - '@rollup/rollup-win32-ia32-msvc': 4.59.0 - '@rollup/rollup-win32-x64-gnu': 4.59.0 - '@rollup/rollup-win32-x64-msvc': 4.59.0 + "@rollup/rollup-android-arm-eabi": 4.59.0 + "@rollup/rollup-android-arm64": 4.59.0 + "@rollup/rollup-darwin-arm64": 4.59.0 + "@rollup/rollup-darwin-x64": 4.59.0 + "@rollup/rollup-freebsd-arm64": 4.59.0 + "@rollup/rollup-freebsd-x64": 4.59.0 + "@rollup/rollup-linux-arm-gnueabihf": 4.59.0 + "@rollup/rollup-linux-arm-musleabihf": 4.59.0 + "@rollup/rollup-linux-arm64-gnu": 4.59.0 + "@rollup/rollup-linux-arm64-musl": 4.59.0 + "@rollup/rollup-linux-loong64-gnu": 4.59.0 + "@rollup/rollup-linux-loong64-musl": 4.59.0 + "@rollup/rollup-linux-ppc64-gnu": 4.59.0 + "@rollup/rollup-linux-ppc64-musl": 4.59.0 + "@rollup/rollup-linux-riscv64-gnu": 4.59.0 + "@rollup/rollup-linux-riscv64-musl": 4.59.0 + "@rollup/rollup-linux-s390x-gnu": 4.59.0 + "@rollup/rollup-linux-x64-gnu": 4.59.0 + "@rollup/rollup-linux-x64-musl": 4.59.0 + "@rollup/rollup-openbsd-x64": 4.59.0 + "@rollup/rollup-openharmony-arm64": 4.59.0 + "@rollup/rollup-win32-arm64-msvc": 4.59.0 + "@rollup/rollup-win32-ia32-msvc": 4.59.0 + "@rollup/rollup-win32-x64-gnu": 4.59.0 + "@rollup/rollup-win32-x64-msvc": 4.59.0 fsevents: 2.3.3 section-matter@1.0.0: @@ -1574,14 +2169,14 @@ snapshots: shiki@3.23.0: dependencies: - '@shikijs/core': 3.23.0 - '@shikijs/engine-javascript': 3.23.0 - '@shikijs/engine-oniguruma': 3.23.0 - '@shikijs/langs': 3.23.0 - '@shikijs/themes': 3.23.0 - '@shikijs/types': 3.23.0 - '@shikijs/vscode-textmate': 10.0.2 - '@types/hast': 3.0.4 + "@shikijs/core": 3.23.0 + "@shikijs/engine-javascript": 3.23.0 + "@shikijs/engine-oniguruma": 3.23.0 + "@shikijs/langs": 3.23.0 + "@shikijs/themes": 3.23.0 + "@shikijs/types": 3.23.0 + "@shikijs/vscode-textmate": 10.0.2 + "@types/hast": 3.0.4 signal-exit@4.1.0: {} @@ -1629,35 +2224,35 @@ snapshots: unist-util-is@6.0.1: dependencies: - '@types/unist': 3.0.3 + "@types/unist": 3.0.3 unist-util-position@5.0.0: dependencies: - '@types/unist': 3.0.3 + "@types/unist": 3.0.3 unist-util-stringify-position@4.0.0: dependencies: - '@types/unist': 3.0.3 + "@types/unist": 3.0.3 unist-util-visit-parents@6.0.2: dependencies: - '@types/unist': 3.0.3 + "@types/unist": 3.0.3 unist-util-is: 6.0.1 unist-util-visit@5.1.0: dependencies: - '@types/unist': 3.0.3 + "@types/unist": 3.0.3 unist-util-is: 6.0.1 unist-util-visit-parents: 6.0.2 vfile-message@4.0.3: dependencies: - '@types/unist': 3.0.3 + "@types/unist": 3.0.3 unist-util-stringify-position: 4.0.0 vfile@6.0.3: dependencies: - '@types/unist': 3.0.3 + "@types/unist": 3.0.3 vfile-message: 4.0.3 vite@7.3.1: @@ -1679,19 +2274,19 @@ snapshots: vitepress@2.0.0-alpha.16(postcss@8.5.8): dependencies: - '@docsearch/css': 4.6.0 - '@docsearch/js': 4.6.0 - '@docsearch/sidepanel-js': 4.6.0 - '@iconify-json/simple-icons': 1.2.74 - '@shikijs/core': 3.23.0 - '@shikijs/transformers': 3.23.0 - '@shikijs/types': 3.23.0 - '@types/markdown-it': 14.1.2 - '@vitejs/plugin-vue': 6.0.5(vite@7.3.1)(vue@3.5.30) - '@vue/devtools-api': 8.1.0 - '@vue/shared': 3.5.30 - '@vueuse/core': 14.2.1(vue@3.5.30) - '@vueuse/integrations': 14.2.1(focus-trap@7.8.0)(vue@3.5.30) + "@docsearch/css": 4.6.0 + "@docsearch/js": 4.6.0 + "@docsearch/sidepanel-js": 4.6.0 + "@iconify-json/simple-icons": 1.2.74 + "@shikijs/core": 3.23.0 + "@shikijs/transformers": 3.23.0 + "@shikijs/types": 3.23.0 + "@types/markdown-it": 14.1.2 + "@vitejs/plugin-vue": 6.0.5(vite@7.3.1)(vue@3.5.30) + "@vue/devtools-api": 8.1.0 + "@vue/shared": 3.5.30 + "@vueuse/core": 14.2.1(vue@3.5.30) + "@vueuse/integrations": 14.2.1(focus-trap@7.8.0)(vue@3.5.30) focus-trap: 7.8.0 mark.js: 8.11.1 minisearch: 7.2.0 @@ -1701,7 +2296,7 @@ snapshots: optionalDependencies: postcss: 8.5.8 transitivePeerDependencies: - - '@types/node' + - "@types/node" - async-validator - axios - change-case @@ -1727,11 +2322,11 @@ snapshots: vue@3.5.30: dependencies: - '@vue/compiler-dom': 3.5.30 - '@vue/compiler-sfc': 3.5.30 - '@vue/runtime-dom': 3.5.30 - '@vue/server-renderer': 3.5.30(vue@3.5.30) - '@vue/shared': 3.5.30 + "@vue/compiler-dom": 3.5.30 + "@vue/compiler-sfc": 3.5.30 + "@vue/runtime-dom": 3.5.30 + "@vue/server-renderer": 3.5.30(vue@3.5.30) + "@vue/shared": 3.5.30 which@2.0.2: dependencies: From ce1d7b301aa412b703c6917732f5891185127240 Mon Sep 17 00:00:00 2001 From: RocketQuack <202538874+Rocket-Quack@users.noreply.github.com> Date: Thu, 19 Mar 2026 11:57:06 +0100 Subject: [PATCH 172/279] fix(lint): resolve pre-commit formatting --- .gitignore | 2 +- .pre-commit-config.yaml | 1 + docs/08-reference/04-framework-comparisons.md | 4 ++++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 4704f2d6..591cbaff 100644 --- a/.gitignore +++ b/.gitignore @@ -31,4 +31,4 @@ node_modules # VitePress **/.vitepress/dist -**/.vitepress/cache \ No newline at end of file +**/.vitepress/cache diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5a1d6036..ef57978e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -34,6 +34,7 @@ repos: rev: v2.4.1 hooks: - id: codespell + exclude: ^docs/pnpm-lock\.yaml$ args: - -L - "ro" diff --git a/docs/08-reference/04-framework-comparisons.md b/docs/08-reference/04-framework-comparisons.md index aec78a54..fa1691e8 100644 --- a/docs/08-reference/04-framework-comparisons.md +++ b/docs/08-reference/04-framework-comparisons.md @@ -56,18 +56,22 @@ bench/ ### 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 From b314cfd60cad11f9f02444d7cb19ecc58002f30b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 19 Mar 2026 11:02:11 +0000 Subject: [PATCH 173/279] chore(deps): bump @isaacs/brace-expansion from 5.0.0 to 5.0.1 in /docs Bumps @isaacs/brace-expansion from 5.0.0 to 5.0.1. --- updated-dependencies: - dependency-name: "@isaacs/brace-expansion" dependency-version: 5.0.1 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- docs/pnpm-lock.yaml | 1856 +++++++++++++++---------------------------- 1 file changed, 631 insertions(+), 1225 deletions(-) diff --git a/docs/pnpm-lock.yaml b/docs/pnpm-lock.yaml index 7497803e..7dbba065 100644 --- a/docs/pnpm-lock.yaml +++ b/docs/pnpm-lock.yaml @@ -1,10 +1,11 @@ -lockfileVersion: "9.0" +lockfileVersion: '9.0' settings: autoInstallPeers: true excludeLinksFromLockfile: false importers: + .: devDependencies: vitepress: @@ -15,744 +16,454 @@ importers: version: 1.33.1 packages: - "@babel/helper-string-parser@7.27.1": - resolution: - { - integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==, - } - engines: { node: ">=6.9.0" } - "@babel/helper-validator-identifier@7.28.5": - resolution: - { - integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==, - } - engines: { node: ">=6.9.0" } + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} + engines: {node: '>=6.9.0'} - "@babel/parser@7.29.0": - resolution: - { - integrity: sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==, - } - engines: { node: ">=6.0.0" } + '@babel/helper-validator-identifier@7.28.5': + resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.29.0': + resolution: {integrity: sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==} + engines: {node: '>=6.0.0'} hasBin: true - "@babel/types@7.29.0": - resolution: - { - integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==, - } - engines: { node: ">=6.9.0" } + '@babel/types@7.29.0': + resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} + engines: {node: '>=6.9.0'} - "@docsearch/css@4.6.0": - resolution: - { - integrity: sha512-YlcAimkXclvqta47g47efzCM5CFxDwv2ClkDfEs/fC/Ak0OxPH2b3czwa4o8O1TRBf+ujFF2RiUwszz2fPVNJQ==, - } + '@docsearch/css@4.6.0': + resolution: {integrity: sha512-YlcAimkXclvqta47g47efzCM5CFxDwv2ClkDfEs/fC/Ak0OxPH2b3czwa4o8O1TRBf+ujFF2RiUwszz2fPVNJQ==} - "@docsearch/js@4.6.0": - resolution: - { - integrity: sha512-9/rbgkm/BgTq46cwxIohvSAz3koOFjnPpg0mwkJItAfzKbQIj+310PvwtgUY1YITDuGCag6yOL50GW2DBkaaBw==, - } + '@docsearch/js@4.6.0': + resolution: {integrity: sha512-9/rbgkm/BgTq46cwxIohvSAz3koOFjnPpg0mwkJItAfzKbQIj+310PvwtgUY1YITDuGCag6yOL50GW2DBkaaBw==} - "@docsearch/sidepanel-js@4.6.0": - resolution: - { - integrity: sha512-lFT5KLwlzUmpoGArCScNoK41l9a22JYsEPwBzMrz+/ILVR5Ax87UphCuiyDFQWEvEmbwzn/kJx5W/O5BUlN1Rw==, - } + '@docsearch/sidepanel-js@4.6.0': + resolution: {integrity: sha512-lFT5KLwlzUmpoGArCScNoK41l9a22JYsEPwBzMrz+/ILVR5Ax87UphCuiyDFQWEvEmbwzn/kJx5W/O5BUlN1Rw==} - "@esbuild/aix-ppc64@0.27.4": - resolution: - { - integrity: sha512-cQPwL2mp2nSmHHJlCyoXgHGhbEPMrEEU5xhkcy3Hs/O7nGZqEpZ2sUtLaL9MORLtDfRvVl2/3PAuEkYZH0Ty8Q==, - } - engines: { node: ">=18" } + '@esbuild/aix-ppc64@0.27.4': + resolution: {integrity: sha512-cQPwL2mp2nSmHHJlCyoXgHGhbEPMrEEU5xhkcy3Hs/O7nGZqEpZ2sUtLaL9MORLtDfRvVl2/3PAuEkYZH0Ty8Q==} + engines: {node: '>=18'} cpu: [ppc64] os: [aix] - "@esbuild/android-arm64@0.27.4": - resolution: - { - integrity: sha512-gdLscB7v75wRfu7QSm/zg6Rx29VLdy9eTr2t44sfTW7CxwAtQghZ4ZnqHk3/ogz7xao0QAgrkradbBzcqFPasw==, - } - engines: { node: ">=18" } + '@esbuild/android-arm64@0.27.4': + resolution: {integrity: sha512-gdLscB7v75wRfu7QSm/zg6Rx29VLdy9eTr2t44sfTW7CxwAtQghZ4ZnqHk3/ogz7xao0QAgrkradbBzcqFPasw==} + engines: {node: '>=18'} cpu: [arm64] os: [android] - "@esbuild/android-arm@0.27.4": - resolution: - { - integrity: sha512-X9bUgvxiC8CHAGKYufLIHGXPJWnr0OCdR0anD2e21vdvgCI8lIfqFbnoeOz7lBjdrAGUhqLZLcQo6MLhTO2DKQ==, - } - engines: { node: ">=18" } + '@esbuild/android-arm@0.27.4': + resolution: {integrity: sha512-X9bUgvxiC8CHAGKYufLIHGXPJWnr0OCdR0anD2e21vdvgCI8lIfqFbnoeOz7lBjdrAGUhqLZLcQo6MLhTO2DKQ==} + engines: {node: '>=18'} cpu: [arm] os: [android] - "@esbuild/android-x64@0.27.4": - resolution: - { - integrity: sha512-PzPFnBNVF292sfpfhiyiXCGSn9HZg5BcAz+ivBuSsl6Rk4ga1oEXAamhOXRFyMcjwr2DVtm40G65N3GLeH1Lvw==, - } - engines: { node: ">=18" } + '@esbuild/android-x64@0.27.4': + resolution: {integrity: sha512-PzPFnBNVF292sfpfhiyiXCGSn9HZg5BcAz+ivBuSsl6Rk4ga1oEXAamhOXRFyMcjwr2DVtm40G65N3GLeH1Lvw==} + engines: {node: '>=18'} cpu: [x64] os: [android] - "@esbuild/darwin-arm64@0.27.4": - resolution: - { - integrity: sha512-b7xaGIwdJlht8ZFCvMkpDN6uiSmnxxK56N2GDTMYPr2/gzvfdQN8rTfBsvVKmIVY/X7EM+/hJKEIbbHs9oA4tQ==, - } - engines: { node: ">=18" } + '@esbuild/darwin-arm64@0.27.4': + resolution: {integrity: sha512-b7xaGIwdJlht8ZFCvMkpDN6uiSmnxxK56N2GDTMYPr2/gzvfdQN8rTfBsvVKmIVY/X7EM+/hJKEIbbHs9oA4tQ==} + engines: {node: '>=18'} cpu: [arm64] os: [darwin] - "@esbuild/darwin-x64@0.27.4": - resolution: - { - integrity: sha512-sR+OiKLwd15nmCdqpXMnuJ9W2kpy0KigzqScqHI3Hqwr7IXxBp3Yva+yJwoqh7rE8V77tdoheRYataNKL4QrPw==, - } - engines: { node: ">=18" } + '@esbuild/darwin-x64@0.27.4': + resolution: {integrity: sha512-sR+OiKLwd15nmCdqpXMnuJ9W2kpy0KigzqScqHI3Hqwr7IXxBp3Yva+yJwoqh7rE8V77tdoheRYataNKL4QrPw==} + engines: {node: '>=18'} cpu: [x64] os: [darwin] - "@esbuild/freebsd-arm64@0.27.4": - resolution: - { - integrity: sha512-jnfpKe+p79tCnm4GVav68A7tUFeKQwQyLgESwEAUzyxk/TJr4QdGog9sqWNcUbr/bZt/O/HXouspuQDd9JxFSw==, - } - engines: { node: ">=18" } + '@esbuild/freebsd-arm64@0.27.4': + resolution: {integrity: sha512-jnfpKe+p79tCnm4GVav68A7tUFeKQwQyLgESwEAUzyxk/TJr4QdGog9sqWNcUbr/bZt/O/HXouspuQDd9JxFSw==} + engines: {node: '>=18'} cpu: [arm64] os: [freebsd] - "@esbuild/freebsd-x64@0.27.4": - resolution: - { - integrity: sha512-2kb4ceA/CpfUrIcTUl1wrP/9ad9Atrp5J94Lq69w7UwOMolPIGrfLSvAKJp0RTvkPPyn6CIWrNy13kyLikZRZQ==, - } - engines: { node: ">=18" } + '@esbuild/freebsd-x64@0.27.4': + resolution: {integrity: sha512-2kb4ceA/CpfUrIcTUl1wrP/9ad9Atrp5J94Lq69w7UwOMolPIGrfLSvAKJp0RTvkPPyn6CIWrNy13kyLikZRZQ==} + engines: {node: '>=18'} cpu: [x64] os: [freebsd] - "@esbuild/linux-arm64@0.27.4": - resolution: - { - integrity: sha512-7nQOttdzVGth1iz57kxg9uCz57dxQLHWxopL6mYuYthohPKEK0vU0C3O21CcBK6KDlkYVcnDXY099HcCDXd9dA==, - } - engines: { node: ">=18" } + '@esbuild/linux-arm64@0.27.4': + resolution: {integrity: sha512-7nQOttdzVGth1iz57kxg9uCz57dxQLHWxopL6mYuYthohPKEK0vU0C3O21CcBK6KDlkYVcnDXY099HcCDXd9dA==} + engines: {node: '>=18'} cpu: [arm64] os: [linux] - "@esbuild/linux-arm@0.27.4": - resolution: - { - integrity: sha512-aBYgcIxX/wd5n2ys0yESGeYMGF+pv6g0DhZr3G1ZG4jMfruU9Tl1i2Z+Wnj9/KjGz1lTLCcorqE2viePZqj4Eg==, - } - engines: { node: ">=18" } + '@esbuild/linux-arm@0.27.4': + resolution: {integrity: sha512-aBYgcIxX/wd5n2ys0yESGeYMGF+pv6g0DhZr3G1ZG4jMfruU9Tl1i2Z+Wnj9/KjGz1lTLCcorqE2viePZqj4Eg==} + engines: {node: '>=18'} cpu: [arm] os: [linux] - "@esbuild/linux-ia32@0.27.4": - resolution: - { - integrity: sha512-oPtixtAIzgvzYcKBQM/qZ3R+9TEUd1aNJQu0HhGyqtx6oS7qTpvjheIWBbes4+qu1bNlo2V4cbkISr8q6gRBFA==, - } - engines: { node: ">=18" } + '@esbuild/linux-ia32@0.27.4': + resolution: {integrity: sha512-oPtixtAIzgvzYcKBQM/qZ3R+9TEUd1aNJQu0HhGyqtx6oS7qTpvjheIWBbes4+qu1bNlo2V4cbkISr8q6gRBFA==} + engines: {node: '>=18'} cpu: [ia32] os: [linux] - "@esbuild/linux-loong64@0.27.4": - resolution: - { - integrity: sha512-8mL/vh8qeCoRcFH2nM8wm5uJP+ZcVYGGayMavi8GmRJjuI3g1v6Z7Ni0JJKAJW+m0EtUuARb6Lmp4hMjzCBWzA==, - } - engines: { node: ">=18" } + '@esbuild/linux-loong64@0.27.4': + resolution: {integrity: sha512-8mL/vh8qeCoRcFH2nM8wm5uJP+ZcVYGGayMavi8GmRJjuI3g1v6Z7Ni0JJKAJW+m0EtUuARb6Lmp4hMjzCBWzA==} + engines: {node: '>=18'} cpu: [loong64] os: [linux] - "@esbuild/linux-mips64el@0.27.4": - resolution: - { - integrity: sha512-1RdrWFFiiLIW7LQq9Q2NES+HiD4NyT8Itj9AUeCl0IVCA459WnPhREKgwrpaIfTOe+/2rdntisegiPWn/r/aAw==, - } - engines: { node: ">=18" } + '@esbuild/linux-mips64el@0.27.4': + resolution: {integrity: sha512-1RdrWFFiiLIW7LQq9Q2NES+HiD4NyT8Itj9AUeCl0IVCA459WnPhREKgwrpaIfTOe+/2rdntisegiPWn/r/aAw==} + engines: {node: '>=18'} cpu: [mips64el] os: [linux] - "@esbuild/linux-ppc64@0.27.4": - resolution: - { - integrity: sha512-tLCwNG47l3sd9lpfyx9LAGEGItCUeRCWeAx6x2Jmbav65nAwoPXfewtAdtbtit/pJFLUWOhpv0FpS6GQAmPrHA==, - } - engines: { node: ">=18" } + '@esbuild/linux-ppc64@0.27.4': + resolution: {integrity: sha512-tLCwNG47l3sd9lpfyx9LAGEGItCUeRCWeAx6x2Jmbav65nAwoPXfewtAdtbtit/pJFLUWOhpv0FpS6GQAmPrHA==} + engines: {node: '>=18'} cpu: [ppc64] os: [linux] - "@esbuild/linux-riscv64@0.27.4": - resolution: - { - integrity: sha512-BnASypppbUWyqjd1KIpU4AUBiIhVr6YlHx/cnPgqEkNoVOhHg+YiSVxM1RLfiy4t9cAulbRGTNCKOcqHrEQLIw==, - } - engines: { node: ">=18" } + '@esbuild/linux-riscv64@0.27.4': + resolution: {integrity: sha512-BnASypppbUWyqjd1KIpU4AUBiIhVr6YlHx/cnPgqEkNoVOhHg+YiSVxM1RLfiy4t9cAulbRGTNCKOcqHrEQLIw==} + engines: {node: '>=18'} cpu: [riscv64] os: [linux] - "@esbuild/linux-s390x@0.27.4": - resolution: - { - integrity: sha512-+eUqgb/Z7vxVLezG8bVB9SfBie89gMueS+I0xYh2tJdw3vqA/0ImZJ2ROeWwVJN59ihBeZ7Tu92dF/5dy5FttA==, - } - engines: { node: ">=18" } + '@esbuild/linux-s390x@0.27.4': + resolution: {integrity: sha512-+eUqgb/Z7vxVLezG8bVB9SfBie89gMueS+I0xYh2tJdw3vqA/0ImZJ2ROeWwVJN59ihBeZ7Tu92dF/5dy5FttA==} + engines: {node: '>=18'} cpu: [s390x] os: [linux] - "@esbuild/linux-x64@0.27.4": - resolution: - { - integrity: sha512-S5qOXrKV8BQEzJPVxAwnryi2+Iq5pB40gTEIT69BQONqR7JH1EPIcQ/Uiv9mCnn05jff9umq/5nqzxlqTOg9NA==, - } - engines: { node: ">=18" } + '@esbuild/linux-x64@0.27.4': + resolution: {integrity: sha512-S5qOXrKV8BQEzJPVxAwnryi2+Iq5pB40gTEIT69BQONqR7JH1EPIcQ/Uiv9mCnn05jff9umq/5nqzxlqTOg9NA==} + engines: {node: '>=18'} cpu: [x64] os: [linux] - "@esbuild/netbsd-arm64@0.27.4": - resolution: - { - integrity: sha512-xHT8X4sb0GS8qTqiwzHqpY00C95DPAq7nAwX35Ie/s+LO9830hrMd3oX0ZMKLvy7vsonee73x0lmcdOVXFzd6Q==, - } - engines: { node: ">=18" } + '@esbuild/netbsd-arm64@0.27.4': + resolution: {integrity: sha512-xHT8X4sb0GS8qTqiwzHqpY00C95DPAq7nAwX35Ie/s+LO9830hrMd3oX0ZMKLvy7vsonee73x0lmcdOVXFzd6Q==} + engines: {node: '>=18'} cpu: [arm64] os: [netbsd] - "@esbuild/netbsd-x64@0.27.4": - resolution: - { - integrity: sha512-RugOvOdXfdyi5Tyv40kgQnI0byv66BFgAqjdgtAKqHoZTbTF2QqfQrFwa7cHEORJf6X2ht+l9ABLMP0dnKYsgg==, - } - engines: { node: ">=18" } + '@esbuild/netbsd-x64@0.27.4': + resolution: {integrity: sha512-RugOvOdXfdyi5Tyv40kgQnI0byv66BFgAqjdgtAKqHoZTbTF2QqfQrFwa7cHEORJf6X2ht+l9ABLMP0dnKYsgg==} + engines: {node: '>=18'} cpu: [x64] os: [netbsd] - "@esbuild/openbsd-arm64@0.27.4": - resolution: - { - integrity: sha512-2MyL3IAaTX+1/qP0O1SwskwcwCoOI4kV2IBX1xYnDDqthmq5ArrW94qSIKCAuRraMgPOmG0RDTA74mzYNQA9ow==, - } - engines: { node: ">=18" } + '@esbuild/openbsd-arm64@0.27.4': + resolution: {integrity: sha512-2MyL3IAaTX+1/qP0O1SwskwcwCoOI4kV2IBX1xYnDDqthmq5ArrW94qSIKCAuRraMgPOmG0RDTA74mzYNQA9ow==} + engines: {node: '>=18'} cpu: [arm64] os: [openbsd] - "@esbuild/openbsd-x64@0.27.4": - resolution: - { - integrity: sha512-u8fg/jQ5aQDfsnIV6+KwLOf1CmJnfu1ShpwqdwC0uA7ZPwFws55Ngc12vBdeUdnuWoQYx/SOQLGDcdlfXhYmXQ==, - } - engines: { node: ">=18" } + '@esbuild/openbsd-x64@0.27.4': + resolution: {integrity: sha512-u8fg/jQ5aQDfsnIV6+KwLOf1CmJnfu1ShpwqdwC0uA7ZPwFws55Ngc12vBdeUdnuWoQYx/SOQLGDcdlfXhYmXQ==} + engines: {node: '>=18'} cpu: [x64] os: [openbsd] - "@esbuild/openharmony-arm64@0.27.4": - resolution: - { - integrity: sha512-JkTZrl6VbyO8lDQO3yv26nNr2RM2yZzNrNHEsj9bm6dOwwu9OYN28CjzZkH57bh4w0I2F7IodpQvUAEd1mbWXg==, - } - engines: { node: ">=18" } + '@esbuild/openharmony-arm64@0.27.4': + resolution: {integrity: sha512-JkTZrl6VbyO8lDQO3yv26nNr2RM2yZzNrNHEsj9bm6dOwwu9OYN28CjzZkH57bh4w0I2F7IodpQvUAEd1mbWXg==} + engines: {node: '>=18'} cpu: [arm64] os: [openharmony] - "@esbuild/sunos-x64@0.27.4": - resolution: - { - integrity: sha512-/gOzgaewZJfeJTlsWhvUEmUG4tWEY2Spp5M20INYRg2ZKl9QPO3QEEgPeRtLjEWSW8FilRNacPOg8R1uaYkA6g==, - } - engines: { node: ">=18" } + '@esbuild/sunos-x64@0.27.4': + resolution: {integrity: sha512-/gOzgaewZJfeJTlsWhvUEmUG4tWEY2Spp5M20INYRg2ZKl9QPO3QEEgPeRtLjEWSW8FilRNacPOg8R1uaYkA6g==} + engines: {node: '>=18'} cpu: [x64] os: [sunos] - "@esbuild/win32-arm64@0.27.4": - resolution: - { - integrity: sha512-Z9SExBg2y32smoDQdf1HRwHRt6vAHLXcxD2uGgO/v2jK7Y718Ix4ndsbNMU/+1Qiem9OiOdaqitioZwxivhXYg==, - } - engines: { node: ">=18" } + '@esbuild/win32-arm64@0.27.4': + resolution: {integrity: sha512-Z9SExBg2y32smoDQdf1HRwHRt6vAHLXcxD2uGgO/v2jK7Y718Ix4ndsbNMU/+1Qiem9OiOdaqitioZwxivhXYg==} + engines: {node: '>=18'} cpu: [arm64] os: [win32] - "@esbuild/win32-ia32@0.27.4": - resolution: - { - integrity: sha512-DAyGLS0Jz5G5iixEbMHi5KdiApqHBWMGzTtMiJ72ZOLhbu/bzxgAe8Ue8CTS3n3HbIUHQz/L51yMdGMeoxXNJw==, - } - engines: { node: ">=18" } + '@esbuild/win32-ia32@0.27.4': + resolution: {integrity: sha512-DAyGLS0Jz5G5iixEbMHi5KdiApqHBWMGzTtMiJ72ZOLhbu/bzxgAe8Ue8CTS3n3HbIUHQz/L51yMdGMeoxXNJw==} + engines: {node: '>=18'} cpu: [ia32] os: [win32] - "@esbuild/win32-x64@0.27.4": - resolution: - { - integrity: sha512-+knoa0BDoeXgkNvvV1vvbZX4+hizelrkwmGJBdT17t8FNPwG2lKemmuMZlmaNQ3ws3DKKCxpb4zRZEIp3UxFCg==, - } - engines: { node: ">=18" } + '@esbuild/win32-x64@0.27.4': + resolution: {integrity: sha512-+knoa0BDoeXgkNvvV1vvbZX4+hizelrkwmGJBdT17t8FNPwG2lKemmuMZlmaNQ3ws3DKKCxpb4zRZEIp3UxFCg==} + engines: {node: '>=18'} cpu: [x64] os: [win32] - "@iconify-json/simple-icons@1.2.74": - resolution: - { - integrity: sha512-yqaohfY6jnYjTVpuTkaBQHrWbdUrQyWXhau0r/0EZiNWYXPX/P8WWwl1DoLH5CbvDjjcWQw5J0zADhgCUklOqA==, - } + '@iconify-json/simple-icons@1.2.74': + resolution: {integrity: sha512-yqaohfY6jnYjTVpuTkaBQHrWbdUrQyWXhau0r/0EZiNWYXPX/P8WWwl1DoLH5CbvDjjcWQw5J0zADhgCUklOqA==} - "@iconify/types@2.0.0": - resolution: - { - integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==, - } + '@iconify/types@2.0.0': + resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} - "@isaacs/balanced-match@4.0.1": - resolution: - { - integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==, - } - engines: { node: 20 || >=22 } + '@isaacs/balanced-match@4.0.1': + resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} + engines: {node: 20 || >=22} - "@isaacs/brace-expansion@5.0.0": - resolution: - { - integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==, - } - engines: { node: 20 || >=22 } + '@isaacs/brace-expansion@5.0.0': + resolution: {integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==} + engines: {node: 20 || >=22} - "@isaacs/cliui@8.0.2": - resolution: - { - integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==, - } - engines: { node: ">=12" } + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} - "@jridgewell/sourcemap-codec@1.5.5": - resolution: - { - integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==, - } + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} - "@rolldown/pluginutils@1.0.0-rc.2": - resolution: - { - integrity: sha512-izyXV/v+cHiRfozX62W9htOAvwMo4/bXKDrQ+vom1L1qRuexPock/7VZDAhnpHCLNejd3NJ6hiab+tO0D44Rgw==, - } + '@rolldown/pluginutils@1.0.0-rc.2': + resolution: {integrity: sha512-izyXV/v+cHiRfozX62W9htOAvwMo4/bXKDrQ+vom1L1qRuexPock/7VZDAhnpHCLNejd3NJ6hiab+tO0D44Rgw==} - "@rollup/rollup-android-arm-eabi@4.59.0": - resolution: - { - integrity: sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==, - } + '@rollup/rollup-android-arm-eabi@4.59.0': + resolution: {integrity: sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==} cpu: [arm] os: [android] - "@rollup/rollup-android-arm64@4.59.0": - resolution: - { - integrity: sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==, - } + '@rollup/rollup-android-arm64@4.59.0': + resolution: {integrity: sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==} cpu: [arm64] os: [android] - "@rollup/rollup-darwin-arm64@4.59.0": - resolution: - { - integrity: sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==, - } + '@rollup/rollup-darwin-arm64@4.59.0': + resolution: {integrity: sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==} cpu: [arm64] os: [darwin] - "@rollup/rollup-darwin-x64@4.59.0": - resolution: - { - integrity: sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==, - } + '@rollup/rollup-darwin-x64@4.59.0': + resolution: {integrity: sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==} cpu: [x64] os: [darwin] - "@rollup/rollup-freebsd-arm64@4.59.0": - resolution: - { - integrity: sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==, - } + '@rollup/rollup-freebsd-arm64@4.59.0': + resolution: {integrity: sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==} cpu: [arm64] os: [freebsd] - "@rollup/rollup-freebsd-x64@4.59.0": - resolution: - { - integrity: sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==, - } + '@rollup/rollup-freebsd-x64@4.59.0': + resolution: {integrity: sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==} cpu: [x64] os: [freebsd] - "@rollup/rollup-linux-arm-gnueabihf@4.59.0": - resolution: - { - integrity: sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==, - } + '@rollup/rollup-linux-arm-gnueabihf@4.59.0': + resolution: {integrity: sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==} cpu: [arm] os: [linux] libc: [glibc] - "@rollup/rollup-linux-arm-musleabihf@4.59.0": - resolution: - { - integrity: sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==, - } + '@rollup/rollup-linux-arm-musleabihf@4.59.0': + resolution: {integrity: sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==} cpu: [arm] os: [linux] libc: [musl] - "@rollup/rollup-linux-arm64-gnu@4.59.0": - resolution: - { - integrity: sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==, - } + '@rollup/rollup-linux-arm64-gnu@4.59.0': + resolution: {integrity: sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==} cpu: [arm64] os: [linux] libc: [glibc] - "@rollup/rollup-linux-arm64-musl@4.59.0": - resolution: - { - integrity: sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==, - } + '@rollup/rollup-linux-arm64-musl@4.59.0': + resolution: {integrity: sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==} cpu: [arm64] os: [linux] libc: [musl] - "@rollup/rollup-linux-loong64-gnu@4.59.0": - resolution: - { - integrity: sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==, - } + '@rollup/rollup-linux-loong64-gnu@4.59.0': + resolution: {integrity: sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==} cpu: [loong64] os: [linux] libc: [glibc] - "@rollup/rollup-linux-loong64-musl@4.59.0": - resolution: - { - integrity: sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==, - } + '@rollup/rollup-linux-loong64-musl@4.59.0': + resolution: {integrity: sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==} cpu: [loong64] os: [linux] libc: [musl] - "@rollup/rollup-linux-ppc64-gnu@4.59.0": - resolution: - { - integrity: sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==, - } + '@rollup/rollup-linux-ppc64-gnu@4.59.0': + resolution: {integrity: sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==} cpu: [ppc64] os: [linux] libc: [glibc] - "@rollup/rollup-linux-ppc64-musl@4.59.0": - resolution: - { - integrity: sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==, - } + '@rollup/rollup-linux-ppc64-musl@4.59.0': + resolution: {integrity: sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==} cpu: [ppc64] os: [linux] libc: [musl] - "@rollup/rollup-linux-riscv64-gnu@4.59.0": - resolution: - { - integrity: sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==, - } + '@rollup/rollup-linux-riscv64-gnu@4.59.0': + resolution: {integrity: sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==} cpu: [riscv64] os: [linux] libc: [glibc] - "@rollup/rollup-linux-riscv64-musl@4.59.0": - resolution: - { - integrity: sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==, - } + '@rollup/rollup-linux-riscv64-musl@4.59.0': + resolution: {integrity: sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==} cpu: [riscv64] os: [linux] libc: [musl] - "@rollup/rollup-linux-s390x-gnu@4.59.0": - resolution: - { - integrity: sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==, - } + '@rollup/rollup-linux-s390x-gnu@4.59.0': + resolution: {integrity: sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==} cpu: [s390x] os: [linux] libc: [glibc] - "@rollup/rollup-linux-x64-gnu@4.59.0": - resolution: - { - integrity: sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==, - } + '@rollup/rollup-linux-x64-gnu@4.59.0': + resolution: {integrity: sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==} cpu: [x64] os: [linux] libc: [glibc] - "@rollup/rollup-linux-x64-musl@4.59.0": - resolution: - { - integrity: sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==, - } + '@rollup/rollup-linux-x64-musl@4.59.0': + resolution: {integrity: sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==} cpu: [x64] os: [linux] libc: [musl] - "@rollup/rollup-openbsd-x64@4.59.0": - resolution: - { - integrity: sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==, - } + '@rollup/rollup-openbsd-x64@4.59.0': + resolution: {integrity: sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==} cpu: [x64] os: [openbsd] - "@rollup/rollup-openharmony-arm64@4.59.0": - resolution: - { - integrity: sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==, - } + '@rollup/rollup-openharmony-arm64@4.59.0': + resolution: {integrity: sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==} cpu: [arm64] os: [openharmony] - "@rollup/rollup-win32-arm64-msvc@4.59.0": - resolution: - { - integrity: sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==, - } + '@rollup/rollup-win32-arm64-msvc@4.59.0': + resolution: {integrity: sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==} cpu: [arm64] os: [win32] - "@rollup/rollup-win32-ia32-msvc@4.59.0": - resolution: - { - integrity: sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==, - } + '@rollup/rollup-win32-ia32-msvc@4.59.0': + resolution: {integrity: sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==} cpu: [ia32] os: [win32] - "@rollup/rollup-win32-x64-gnu@4.59.0": - resolution: - { - integrity: sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==, - } + '@rollup/rollup-win32-x64-gnu@4.59.0': + resolution: {integrity: sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==} cpu: [x64] os: [win32] - "@rollup/rollup-win32-x64-msvc@4.59.0": - resolution: - { - integrity: sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==, - } + '@rollup/rollup-win32-x64-msvc@4.59.0': + resolution: {integrity: sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==} cpu: [x64] os: [win32] - "@shikijs/core@3.23.0": - resolution: - { - integrity: sha512-NSWQz0riNb67xthdm5br6lAkvpDJRTgB36fxlo37ZzM2yq0PQFFzbd8psqC2XMPgCzo1fW6cVi18+ArJ44wqgA==, - } + '@shikijs/core@3.23.0': + resolution: {integrity: sha512-NSWQz0riNb67xthdm5br6lAkvpDJRTgB36fxlo37ZzM2yq0PQFFzbd8psqC2XMPgCzo1fW6cVi18+ArJ44wqgA==} - "@shikijs/engine-javascript@3.23.0": - resolution: - { - integrity: sha512-aHt9eiGFobmWR5uqJUViySI1bHMqrAgamWE1TYSUoftkAeCCAiGawPMwM+VCadylQtF4V3VNOZ5LmfItH5f3yA==, - } + '@shikijs/engine-javascript@3.23.0': + resolution: {integrity: sha512-aHt9eiGFobmWR5uqJUViySI1bHMqrAgamWE1TYSUoftkAeCCAiGawPMwM+VCadylQtF4V3VNOZ5LmfItH5f3yA==} - "@shikijs/engine-oniguruma@3.23.0": - resolution: - { - integrity: sha512-1nWINwKXxKKLqPibT5f4pAFLej9oZzQTsby8942OTlsJzOBZ0MWKiwzMsd+jhzu8YPCHAswGnnN1YtQfirL35g==, - } + '@shikijs/engine-oniguruma@3.23.0': + resolution: {integrity: sha512-1nWINwKXxKKLqPibT5f4pAFLej9oZzQTsby8942OTlsJzOBZ0MWKiwzMsd+jhzu8YPCHAswGnnN1YtQfirL35g==} - "@shikijs/langs@3.23.0": - resolution: - { - integrity: sha512-2Ep4W3Re5aB1/62RSYQInK9mM3HsLeB91cHqznAJMuylqjzNVAVCMnNWRHFtcNHXsoNRayP9z1qj4Sq3nMqYXg==, - } + '@shikijs/langs@3.23.0': + resolution: {integrity: sha512-2Ep4W3Re5aB1/62RSYQInK9mM3HsLeB91cHqznAJMuylqjzNVAVCMnNWRHFtcNHXsoNRayP9z1qj4Sq3nMqYXg==} - "@shikijs/themes@3.23.0": - resolution: - { - integrity: sha512-5qySYa1ZgAT18HR/ypENL9cUSGOeI2x+4IvYJu4JgVJdizn6kG4ia5Q1jDEOi7gTbN4RbuYtmHh0W3eccOrjMA==, - } + '@shikijs/themes@3.23.0': + resolution: {integrity: sha512-5qySYa1ZgAT18HR/ypENL9cUSGOeI2x+4IvYJu4JgVJdizn6kG4ia5Q1jDEOi7gTbN4RbuYtmHh0W3eccOrjMA==} - "@shikijs/transformers@3.23.0": - resolution: - { - integrity: sha512-F9msZVxdF+krQNSdQ4V+Ja5QemeAoTQ2jxt7nJCwhDsdF1JWS3KxIQXA3lQbyKwS3J61oHRUSv4jYWv3CkaKTQ==, - } + '@shikijs/transformers@3.23.0': + resolution: {integrity: sha512-F9msZVxdF+krQNSdQ4V+Ja5QemeAoTQ2jxt7nJCwhDsdF1JWS3KxIQXA3lQbyKwS3J61oHRUSv4jYWv3CkaKTQ==} - "@shikijs/types@3.23.0": - resolution: - { - integrity: sha512-3JZ5HXOZfYjsYSk0yPwBrkupyYSLpAE26Qc0HLghhZNGTZg/SKxXIIgoxOpmmeQP0RRSDJTk1/vPfw9tbw+jSQ==, - } + '@shikijs/types@3.23.0': + resolution: {integrity: sha512-3JZ5HXOZfYjsYSk0yPwBrkupyYSLpAE26Qc0HLghhZNGTZg/SKxXIIgoxOpmmeQP0RRSDJTk1/vPfw9tbw+jSQ==} - "@shikijs/vscode-textmate@10.0.2": - resolution: - { - integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==, - } + '@shikijs/vscode-textmate@10.0.2': + resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} - "@types/estree@1.0.8": - resolution: - { - integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==, - } + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} - "@types/hast@3.0.4": - resolution: - { - integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==, - } + '@types/hast@3.0.4': + resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} - "@types/linkify-it@5.0.0": - resolution: - { - integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==, - } + '@types/linkify-it@5.0.0': + resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==} - "@types/markdown-it@14.1.2": - resolution: - { - integrity: sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==, - } + '@types/markdown-it@14.1.2': + resolution: {integrity: sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==} - "@types/mdast@4.0.4": - resolution: - { - integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==, - } + '@types/mdast@4.0.4': + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} - "@types/mdurl@2.0.0": - resolution: - { - integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==, - } + '@types/mdurl@2.0.0': + resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==} - "@types/unist@3.0.3": - resolution: - { - integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==, - } + '@types/unist@3.0.3': + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} - "@types/web-bluetooth@0.0.21": - resolution: - { - integrity: sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==, - } + '@types/web-bluetooth@0.0.21': + resolution: {integrity: sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==} - "@ungap/structured-clone@1.3.0": - resolution: - { - integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==, - } + '@ungap/structured-clone@1.3.0': + resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} - "@vitejs/plugin-vue@6.0.5": - resolution: - { - integrity: sha512-bL3AxKuQySfk1iGcBsQnoRVexTPJq0Z/ixFVM8OhVJAP6ZXXXLtM7NFKWhLl30Kg7uTBqIaPXbh+nuQCuBDedg==, - } - engines: { node: ^20.19.0 || >=22.12.0 } + '@vitejs/plugin-vue@6.0.5': + resolution: {integrity: sha512-bL3AxKuQySfk1iGcBsQnoRVexTPJq0Z/ixFVM8OhVJAP6ZXXXLtM7NFKWhLl30Kg7uTBqIaPXbh+nuQCuBDedg==} + engines: {node: ^20.19.0 || >=22.12.0} peerDependencies: vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 vue: ^3.2.25 - "@vue/compiler-core@3.5.30": - resolution: - { - integrity: sha512-s3DfdZkcu/qExZ+td75015ljzHc6vE+30cFMGRPROYjqkroYI5NV2X1yAMX9UeyBNWB9MxCfPcsjpLS11nzkkw==, - } + '@vue/compiler-core@3.5.30': + resolution: {integrity: sha512-s3DfdZkcu/qExZ+td75015ljzHc6vE+30cFMGRPROYjqkroYI5NV2X1yAMX9UeyBNWB9MxCfPcsjpLS11nzkkw==} - "@vue/compiler-dom@3.5.30": - resolution: - { - integrity: sha512-eCFYESUEVYHhiMuK4SQTldO3RYxyMR/UQL4KdGD1Yrkfdx4m/HYuZ9jSfPdA+nWJY34VWndiYdW/wZXyiPEB9g==, - } + '@vue/compiler-dom@3.5.30': + resolution: {integrity: sha512-eCFYESUEVYHhiMuK4SQTldO3RYxyMR/UQL4KdGD1Yrkfdx4m/HYuZ9jSfPdA+nWJY34VWndiYdW/wZXyiPEB9g==} - "@vue/compiler-sfc@3.5.30": - resolution: - { - integrity: sha512-LqmFPDn89dtU9vI3wHJnwaV6GfTRD87AjWpTWpyrdVOObVtjIuSeZr181z5C4PmVx/V3j2p+0f7edFKGRMpQ5A==, - } + '@vue/compiler-sfc@3.5.30': + resolution: {integrity: sha512-LqmFPDn89dtU9vI3wHJnwaV6GfTRD87AjWpTWpyrdVOObVtjIuSeZr181z5C4PmVx/V3j2p+0f7edFKGRMpQ5A==} - "@vue/compiler-ssr@3.5.30": - resolution: - { - integrity: sha512-NsYK6OMTnx109PSL2IAyf62JP6EUdk4Dmj6AkWcJGBvN0dQoMYtVekAmdqgTtWQgEJo+Okstbf/1p7qZr5H+bA==, - } + '@vue/compiler-ssr@3.5.30': + resolution: {integrity: sha512-NsYK6OMTnx109PSL2IAyf62JP6EUdk4Dmj6AkWcJGBvN0dQoMYtVekAmdqgTtWQgEJo+Okstbf/1p7qZr5H+bA==} - "@vue/devtools-api@8.1.0": - resolution: - { - integrity: sha512-O44X57jjkLKbLEc4OgL/6fEPOOanRJU8kYpCE8qfKlV96RQZcdzrcLI5mxMuVRUeXhHKIHGhCpHacyCk0HyO4w==, - } + '@vue/devtools-api@8.1.0': + resolution: {integrity: sha512-O44X57jjkLKbLEc4OgL/6fEPOOanRJU8kYpCE8qfKlV96RQZcdzrcLI5mxMuVRUeXhHKIHGhCpHacyCk0HyO4w==} - "@vue/devtools-kit@8.1.0": - resolution: - { - integrity: sha512-/NZlS4WtGIB54DA/z10gzk+n/V7zaqSzYZOVlg2CfdnpIKdB61bd7JDIMxf/zrtX41zod8E2/bbEBoW/d7x70Q==, - } + '@vue/devtools-kit@8.1.0': + resolution: {integrity: sha512-/NZlS4WtGIB54DA/z10gzk+n/V7zaqSzYZOVlg2CfdnpIKdB61bd7JDIMxf/zrtX41zod8E2/bbEBoW/d7x70Q==} - "@vue/devtools-shared@8.1.0": - resolution: - { - integrity: sha512-h8uCb4Qs8UT8VdTT5yjY6tOJ//qH7EpxToixR0xqejR55t5OdISIg7AJ7eBkhBs8iu1qG5gY3QQNN1DF1EelAA==, - } + '@vue/devtools-shared@8.1.0': + resolution: {integrity: sha512-h8uCb4Qs8UT8VdTT5yjY6tOJ//qH7EpxToixR0xqejR55t5OdISIg7AJ7eBkhBs8iu1qG5gY3QQNN1DF1EelAA==} - "@vue/reactivity@3.5.30": - resolution: - { - integrity: sha512-179YNgKATuwj9gB+66snskRDOitDiuOZqkYia7mHKJaidOMo/WJxHKF8DuGc4V4XbYTJANlfEKb0yxTQotnx4Q==, - } + '@vue/reactivity@3.5.30': + resolution: {integrity: sha512-179YNgKATuwj9gB+66snskRDOitDiuOZqkYia7mHKJaidOMo/WJxHKF8DuGc4V4XbYTJANlfEKb0yxTQotnx4Q==} - "@vue/runtime-core@3.5.30": - resolution: - { - integrity: sha512-e0Z+8PQsUTdwV8TtEsLzUM7SzC7lQwYKePydb7K2ZnmS6jjND+WJXkmmfh/swYzRyfP1EY3fpdesyYoymCzYfg==, - } + '@vue/runtime-core@3.5.30': + resolution: {integrity: sha512-e0Z+8PQsUTdwV8TtEsLzUM7SzC7lQwYKePydb7K2ZnmS6jjND+WJXkmmfh/swYzRyfP1EY3fpdesyYoymCzYfg==} - "@vue/runtime-dom@3.5.30": - resolution: - { - integrity: sha512-2UIGakjU4WSQ0T4iwDEW0W7vQj6n7AFn7taqZ9Cvm0Q/RA2FFOziLESrDL4GmtI1wV3jXg5nMoJSYO66egDUBw==, - } + '@vue/runtime-dom@3.5.30': + resolution: {integrity: sha512-2UIGakjU4WSQ0T4iwDEW0W7vQj6n7AFn7taqZ9Cvm0Q/RA2FFOziLESrDL4GmtI1wV3jXg5nMoJSYO66egDUBw==} - "@vue/server-renderer@3.5.30": - resolution: - { - integrity: sha512-v+R34icapydRwbZRD0sXwtHqrQJv38JuMB4JxbOxd8NEpGLny7cncMp53W9UH/zo4j8eDHjQ1dEJXwzFQknjtQ==, - } + '@vue/server-renderer@3.5.30': + resolution: {integrity: sha512-v+R34icapydRwbZRD0sXwtHqrQJv38JuMB4JxbOxd8NEpGLny7cncMp53W9UH/zo4j8eDHjQ1dEJXwzFQknjtQ==} peerDependencies: vue: 3.5.30 - "@vue/shared@3.5.30": - resolution: - { - integrity: sha512-YXgQ7JjaO18NeK2K9VTbDHaFy62WrObMa6XERNfNOkAhD1F1oDSf3ZJ7K6GqabZ0BvSDHajp8qfS5Sa2I9n8uQ==, - } + '@vue/shared@3.5.30': + resolution: {integrity: sha512-YXgQ7JjaO18NeK2K9VTbDHaFy62WrObMa6XERNfNOkAhD1F1oDSf3ZJ7K6GqabZ0BvSDHajp8qfS5Sa2I9n8uQ==} - "@vueuse/core@14.2.1": - resolution: - { - integrity: sha512-3vwDzV+GDUNpdegRY6kzpLm4Igptq+GA0QkJ3W61Iv27YWwW/ufSlOfgQIpN6FZRMG0mkaz4gglJRtq5SeJyIQ==, - } + '@vueuse/core@14.2.1': + resolution: {integrity: sha512-3vwDzV+GDUNpdegRY6kzpLm4Igptq+GA0QkJ3W61Iv27YWwW/ufSlOfgQIpN6FZRMG0mkaz4gglJRtq5SeJyIQ==} peerDependencies: vue: ^3.5.0 - "@vueuse/integrations@14.2.1": - resolution: - { - integrity: sha512-2LIUpBi/67PoXJGqSDQUF0pgQWpNHh7beiA+KG2AbybcNm+pTGWT6oPGlBgUoDWmYwfeQqM/uzOHqcILpKL7nA==, - } + '@vueuse/integrations@14.2.1': + resolution: {integrity: sha512-2LIUpBi/67PoXJGqSDQUF0pgQWpNHh7beiA+KG2AbybcNm+pTGWT6oPGlBgUoDWmYwfeQqM/uzOHqcILpKL7nA==} peerDependencies: async-validator: ^4 axios: ^1 @@ -793,183 +504,102 @@ packages: universal-cookie: optional: true - "@vueuse/metadata@14.2.1": - resolution: - { - integrity: sha512-1ButlVtj5Sb/HDtIy1HFr1VqCP4G6Ypqt5MAo0lCgjokrk2mvQKsK2uuy0vqu/Ks+sHfuHo0B9Y9jn9xKdjZsw==, - } + '@vueuse/metadata@14.2.1': + resolution: {integrity: sha512-1ButlVtj5Sb/HDtIy1HFr1VqCP4G6Ypqt5MAo0lCgjokrk2mvQKsK2uuy0vqu/Ks+sHfuHo0B9Y9jn9xKdjZsw==} - "@vueuse/shared@14.2.1": - resolution: - { - integrity: sha512-shTJncjV9JTI4oVNyF1FQonetYAiTBd+Qj7cY89SWbXSkx7gyhrgtEdF2ZAVWS1S3SHlaROO6F2IesJxQEkZBw==, - } + '@vueuse/shared@14.2.1': + resolution: {integrity: sha512-shTJncjV9JTI4oVNyF1FQonetYAiTBd+Qj7cY89SWbXSkx7gyhrgtEdF2ZAVWS1S3SHlaROO6F2IesJxQEkZBw==} peerDependencies: vue: ^3.5.0 ansi-regex@5.0.1: - resolution: - { - integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} ansi-regex@6.2.2: - resolution: - { - integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==, - } - engines: { node: ">=12" } + resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} + engines: {node: '>=12'} ansi-styles@4.3.0: - resolution: - { - integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} ansi-styles@6.2.3: - resolution: - { - integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==, - } - engines: { node: ">=12" } + resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} + engines: {node: '>=12'} argparse@1.0.10: - resolution: - { - integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==, - } + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} birpc@2.9.0: - resolution: - { - integrity: sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw==, - } + resolution: {integrity: sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw==} ccount@2.0.1: - resolution: - { - integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==, - } + resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} character-entities-html4@2.1.0: - resolution: - { - integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==, - } + resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} character-entities-legacy@3.0.0: - resolution: - { - integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==, - } + resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} color-convert@2.0.1: - resolution: - { - integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==, - } - engines: { node: ">=7.0.0" } + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} color-name@1.1.4: - resolution: - { - integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==, - } + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} comma-separated-tokens@2.0.3: - resolution: - { - integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==, - } + resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} cross-spawn@7.0.6: - resolution: - { - integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==, - } - engines: { node: ">= 8" } + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} csstype@3.2.3: - resolution: - { - integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==, - } + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} dequal@2.0.3: - resolution: - { - integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==, - } - engines: { node: ">=6" } + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} devlop@1.1.0: - resolution: - { - integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==, - } + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} eastasianwidth@0.2.0: - resolution: - { - integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==, - } + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} emoji-regex@8.0.0: - resolution: - { - integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==, - } + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} emoji-regex@9.2.2: - resolution: - { - integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==, - } + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} entities@7.0.1: - resolution: - { - integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==, - } - engines: { node: ">=0.12" } + resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==} + engines: {node: '>=0.12'} esbuild@0.27.4: - resolution: - { - integrity: sha512-Rq4vbHnYkK5fws5NF7MYTU68FPRE1ajX7heQ/8QXXWqNgqqJ/GkmmyxIzUnf2Sr/bakf8l54716CcMGHYhMrrQ==, - } - engines: { node: ">=18" } + resolution: {integrity: sha512-Rq4vbHnYkK5fws5NF7MYTU68FPRE1ajX7heQ/8QXXWqNgqqJ/GkmmyxIzUnf2Sr/bakf8l54716CcMGHYhMrrQ==} + engines: {node: '>=18'} hasBin: true esprima@4.0.1: - resolution: - { - integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==, - } - engines: { node: ">=4" } + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} hasBin: true estree-walker@2.0.2: - resolution: - { - integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==, - } + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} extend-shallow@2.0.1: - resolution: - { - integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==, - } - engines: { node: ">=0.10.0" } + resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} + engines: {node: '>=0.10.0'} fdir@6.5.0: - resolution: - { - integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==, - } - engines: { node: ">=12.0.0" } + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} peerDependencies: picomatch: ^3 || ^4 peerDependenciesMeta: @@ -977,463 +607,259 @@ packages: optional: true focus-trap@7.8.0: - resolution: - { - integrity: sha512-/yNdlIkpWbM0ptxno3ONTuf+2g318kh2ez3KSeZN5dZ8YC6AAmgeWz+GasYYiBJPFaYcSAPeu4GfhUaChzIJXA==, - } + resolution: {integrity: sha512-/yNdlIkpWbM0ptxno3ONTuf+2g318kh2ez3KSeZN5dZ8YC6AAmgeWz+GasYYiBJPFaYcSAPeu4GfhUaChzIJXA==} foreground-child@3.3.1: - resolution: - { - integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==, - } - engines: { node: ">=14" } + resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} + engines: {node: '>=14'} fsevents@2.3.3: - resolution: - { - integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==, - } - engines: { node: ^8.16.0 || ^10.6.0 || >=11.0.0 } + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] glob@11.1.0: - resolution: - { - integrity: sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==, - } - engines: { node: 20 || >=22 } + resolution: {integrity: sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==} + engines: {node: 20 || >=22} deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me hasBin: true gray-matter@4.0.3: - resolution: - { - integrity: sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==, - } - engines: { node: ">=6.0" } + resolution: {integrity: sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==} + engines: {node: '>=6.0'} hast-util-to-html@9.0.5: - resolution: - { - integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==, - } + resolution: {integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==} hast-util-whitespace@3.0.0: - resolution: - { - integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==, - } + resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} hookable@5.5.3: - resolution: - { - integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==, - } + resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==} html-void-elements@3.0.0: - resolution: - { - integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==, - } + resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} is-extendable@0.1.1: - resolution: - { - integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==, - } - engines: { node: ">=0.10.0" } + resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} + engines: {node: '>=0.10.0'} is-fullwidth-code-point@3.0.0: - resolution: - { - integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} isexe@2.0.0: - resolution: - { - integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==, - } + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} jackspeak@4.1.1: - resolution: - { - integrity: sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==, - } - engines: { node: 20 || >=22 } + resolution: {integrity: sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==} + engines: {node: 20 || >=22} js-yaml@3.14.2: - resolution: - { - integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==, - } + resolution: {integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==} hasBin: true kind-of@6.0.3: - resolution: - { - integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==, - } - engines: { node: ">=0.10.0" } + resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} + engines: {node: '>=0.10.0'} lru-cache@11.2.4: - resolution: - { - integrity: sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==, - } - engines: { node: 20 || >=22 } + resolution: {integrity: sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==} + engines: {node: 20 || >=22} magic-string@0.30.21: - resolution: - { - integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==, - } + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} mark.js@8.11.1: - resolution: - { - integrity: sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==, - } + resolution: {integrity: sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==} mdast-util-to-hast@13.2.1: - resolution: - { - integrity: sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==, - } + resolution: {integrity: sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==} micromark-util-character@2.1.1: - resolution: - { - integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==, - } + resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} micromark-util-encode@2.0.1: - resolution: - { - integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==, - } + resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} micromark-util-sanitize-uri@2.0.1: - resolution: - { - integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==, - } + resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} micromark-util-symbol@2.0.1: - resolution: - { - integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==, - } + resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} micromark-util-types@2.0.2: - resolution: - { - integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==, - } + resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} minimatch@10.1.1: - resolution: - { - integrity: sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==, - } - engines: { node: 20 || >=22 } + resolution: {integrity: sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==} + engines: {node: 20 || >=22} minipass@7.1.2: - resolution: - { - integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==, - } - engines: { node: ">=16 || 14 >=14.17" } + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} minisearch@7.2.0: - resolution: - { - integrity: sha512-dqT2XBYUOZOiC5t2HRnwADjhNS2cecp9u+TJRiJ1Qp/f5qjkeT5APcGPjHw+bz89Ms8Jp+cG4AlE+QZ/QnDglg==, - } + resolution: {integrity: sha512-dqT2XBYUOZOiC5t2HRnwADjhNS2cecp9u+TJRiJ1Qp/f5qjkeT5APcGPjHw+bz89Ms8Jp+cG4AlE+QZ/QnDglg==} nanoid@3.3.11: - resolution: - { - integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==, - } - engines: { node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1 } + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true oniguruma-parser@0.12.1: - resolution: - { - integrity: sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w==, - } + resolution: {integrity: sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w==} oniguruma-to-es@4.3.5: - resolution: - { - integrity: sha512-Zjygswjpsewa0NLTsiizVuMQZbp0MDyM6lIt66OxsF21npUDlzpHi1Mgb/qhQdkb+dWFTzJmFbEWdvZgRho8eQ==, - } + resolution: {integrity: sha512-Zjygswjpsewa0NLTsiizVuMQZbp0MDyM6lIt66OxsF21npUDlzpHi1Mgb/qhQdkb+dWFTzJmFbEWdvZgRho8eQ==} package-json-from-dist@1.0.1: - resolution: - { - integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==, - } + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} path-key@3.1.1: - resolution: - { - integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} path-scurry@2.0.1: - resolution: - { - integrity: sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==, - } - engines: { node: 20 || >=22 } + resolution: {integrity: sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==} + engines: {node: 20 || >=22} perfect-debounce@2.1.0: - resolution: - { - integrity: sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g==, - } + resolution: {integrity: sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g==} picocolors@1.1.1: - resolution: - { - integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==, - } + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} picomatch@4.0.3: - resolution: - { - integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==, - } - engines: { node: ">=12" } + resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} + engines: {node: '>=12'} postcss@8.5.8: - resolution: - { - integrity: sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==, - } - engines: { node: ^10 || ^12 || >=14 } + resolution: {integrity: sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==} + engines: {node: ^10 || ^12 || >=14} property-information@7.1.0: - resolution: - { - integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==, - } + resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==} qsu@1.10.4: - resolution: - { - integrity: sha512-v5RhwvHMkDdbXEaAxQh5re8q7DiG6EE70+CNwYVA6wZsa4gUrpur+D8lIO3PrzeCj3azc/S79X5v3BH8ILfr9A==, - } - engines: { node: ">=18.0.0" } + resolution: {integrity: sha512-v5RhwvHMkDdbXEaAxQh5re8q7DiG6EE70+CNwYVA6wZsa4gUrpur+D8lIO3PrzeCj3azc/S79X5v3BH8ILfr9A==} + engines: {node: '>=18.0.0'} regex-recursion@6.0.2: - resolution: - { - integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==, - } + resolution: {integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==} regex-utilities@2.3.0: - resolution: - { - integrity: sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==, - } + resolution: {integrity: sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==} regex@6.1.0: - resolution: - { - integrity: sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==, - } + resolution: {integrity: sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==} rollup@4.59.0: - resolution: - { - integrity: sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==, - } - engines: { node: ">=18.0.0", npm: ">=8.0.0" } + resolution: {integrity: sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true section-matter@1.0.0: - resolution: - { - integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==, - } - engines: { node: ">=4" } + resolution: {integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==} + engines: {node: '>=4'} shebang-command@2.0.0: - resolution: - { - integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} shebang-regex@3.0.0: - resolution: - { - integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} shiki@3.23.0: - resolution: - { - integrity: sha512-55Dj73uq9ZXL5zyeRPzHQsK7Nbyt6Y10k5s7OjuFZGMhpp4r/rsLBH0o/0fstIzX1Lep9VxefWljK/SKCzygIA==, - } + resolution: {integrity: sha512-55Dj73uq9ZXL5zyeRPzHQsK7Nbyt6Y10k5s7OjuFZGMhpp4r/rsLBH0o/0fstIzX1Lep9VxefWljK/SKCzygIA==} signal-exit@4.1.0: - resolution: - { - integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==, - } - engines: { node: ">=14" } + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} source-map-js@1.2.1: - resolution: - { - integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==, - } - engines: { node: ">=0.10.0" } + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} space-separated-tokens@2.0.2: - resolution: - { - integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==, - } + resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} sprintf-js@1.0.3: - resolution: - { - integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==, - } + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} string-width@4.2.3: - resolution: - { - integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} string-width@5.1.2: - resolution: - { - integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==, - } - engines: { node: ">=12" } + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} stringify-entities@4.0.4: - resolution: - { - integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==, - } + resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} strip-ansi@6.0.1: - resolution: - { - integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} strip-ansi@7.1.2: - resolution: - { - integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==, - } - engines: { node: ">=12" } + resolution: {integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==} + engines: {node: '>=12'} strip-bom-string@1.0.0: - resolution: - { - integrity: sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==, - } - engines: { node: ">=0.10.0" } + resolution: {integrity: sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==} + engines: {node: '>=0.10.0'} tabbable@6.4.0: - resolution: - { - integrity: sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg==, - } + resolution: {integrity: sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg==} tinyglobby@0.2.15: - resolution: - { - integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==, - } - engines: { node: ">=12.0.0" } + resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} + engines: {node: '>=12.0.0'} trim-lines@3.0.1: - resolution: - { - integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==, - } + resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} unist-util-is@6.0.1: - resolution: - { - integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==, - } + resolution: {integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==} unist-util-position@5.0.0: - resolution: - { - integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==, - } + resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} unist-util-stringify-position@4.0.0: - resolution: - { - integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==, - } + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} unist-util-visit-parents@6.0.2: - resolution: - { - integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==, - } + resolution: {integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==} unist-util-visit@5.1.0: - resolution: - { - integrity: sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==, - } + resolution: {integrity: sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==} vfile-message@4.0.3: - resolution: - { - integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==, - } + resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} vfile@6.0.3: - resolution: - { - integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==, - } + resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} vite@7.3.1: - resolution: - { - integrity: sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==, - } - engines: { node: ^20.19.0 || >=22.12.0 } + resolution: {integrity: sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==} + engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: - "@types/node": ^20.19.0 || >=22.12.0 - jiti: ">=1.21.0" + '@types/node': ^20.19.0 || >=22.12.0 + jiti: '>=1.21.0' less: ^4.0.0 lightningcss: ^1.21.0 sass: ^1.70.0 sass-embedded: ^1.70.0 - stylus: ">=0.54.8" + stylus: '>=0.54.8' sugarss: ^5.0.0 terser: ^5.16.0 tsx: ^4.8.1 yaml: ^2.4.2 peerDependenciesMeta: - "@types/node": + '@types/node': optional: true jiti: optional: true @@ -1457,21 +883,15 @@ packages: optional: true vitepress-sidebar@1.33.1: - resolution: - { - integrity: sha512-wPUbXezGakVldawixeRW5tKQTLKoMj2t4nWoThKfCltBM/9a38IE+wCXmmRNW22ZKC32SD/X/sG6NyCTK8QBRg==, - } - engines: { node: ">=18.0.0" } + resolution: {integrity: sha512-wPUbXezGakVldawixeRW5tKQTLKoMj2t4nWoThKfCltBM/9a38IE+wCXmmRNW22ZKC32SD/X/sG6NyCTK8QBRg==} + engines: {node: '>=18.0.0'} vitepress@2.0.0-alpha.16: - resolution: - { - integrity: sha512-w1nwsefDVIsje7BZr2tsKxkZutDGjG0YoQ2yxO7+a9tvYVqfljYbwj5LMYkPy8Tb7YbPwa22HtIhk62jbrvuEQ==, - } + resolution: {integrity: sha512-w1nwsefDVIsje7BZr2tsKxkZutDGjG0YoQ2yxO7+a9tvYVqfljYbwj5LMYkPy8Tb7YbPwa22HtIhk62jbrvuEQ==} hasBin: true peerDependencies: markdown-it-mathjax3: ^4 - oxc-minify: "*" + oxc-minify: '*' postcss: ^8 peerDependenciesMeta: markdown-it-mathjax3: @@ -1482,155 +902,141 @@ packages: optional: true vue@3.5.30: - resolution: - { - integrity: sha512-hTHLc6VNZyzzEH/l7PFGjpcTvUgiaPK5mdLkbjrTeWSRcEfxFrv56g/XckIYlE9ckuobsdwqd5mk2g1sBkMewg==, - } + resolution: {integrity: sha512-hTHLc6VNZyzzEH/l7PFGjpcTvUgiaPK5mdLkbjrTeWSRcEfxFrv56g/XckIYlE9ckuobsdwqd5mk2g1sBkMewg==} peerDependencies: - typescript: "*" + typescript: '*' peerDependenciesMeta: typescript: optional: true which@2.0.2: - resolution: - { - integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==, - } - engines: { node: ">= 8" } + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} hasBin: true wrap-ansi@7.0.0: - resolution: - { - integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==, - } - engines: { node: ">=10" } + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} wrap-ansi@8.1.0: - resolution: - { - integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==, - } - engines: { node: ">=12" } + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} zwitch@2.0.4: - resolution: - { - integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==, - } + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} snapshots: - "@babel/helper-string-parser@7.27.1": {} - "@babel/helper-validator-identifier@7.28.5": {} + '@babel/helper-string-parser@7.27.1': {} - "@babel/parser@7.29.0": + '@babel/helper-validator-identifier@7.28.5': {} + + '@babel/parser@7.29.0': dependencies: - "@babel/types": 7.29.0 + '@babel/types': 7.29.0 - "@babel/types@7.29.0": + '@babel/types@7.29.0': dependencies: - "@babel/helper-string-parser": 7.27.1 - "@babel/helper-validator-identifier": 7.28.5 + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 - "@docsearch/css@4.6.0": {} + '@docsearch/css@4.6.0': {} - "@docsearch/js@4.6.0": {} + '@docsearch/js@4.6.0': {} - "@docsearch/sidepanel-js@4.6.0": {} + '@docsearch/sidepanel-js@4.6.0': {} - "@esbuild/aix-ppc64@0.27.4": + '@esbuild/aix-ppc64@0.27.4': optional: true - "@esbuild/android-arm64@0.27.4": + '@esbuild/android-arm64@0.27.4': optional: true - "@esbuild/android-arm@0.27.4": + '@esbuild/android-arm@0.27.4': optional: true - "@esbuild/android-x64@0.27.4": + '@esbuild/android-x64@0.27.4': optional: true - "@esbuild/darwin-arm64@0.27.4": + '@esbuild/darwin-arm64@0.27.4': optional: true - "@esbuild/darwin-x64@0.27.4": + '@esbuild/darwin-x64@0.27.4': optional: true - "@esbuild/freebsd-arm64@0.27.4": + '@esbuild/freebsd-arm64@0.27.4': optional: true - "@esbuild/freebsd-x64@0.27.4": + '@esbuild/freebsd-x64@0.27.4': optional: true - "@esbuild/linux-arm64@0.27.4": + '@esbuild/linux-arm64@0.27.4': optional: true - "@esbuild/linux-arm@0.27.4": + '@esbuild/linux-arm@0.27.4': optional: true - "@esbuild/linux-ia32@0.27.4": + '@esbuild/linux-ia32@0.27.4': optional: true - "@esbuild/linux-loong64@0.27.4": + '@esbuild/linux-loong64@0.27.4': optional: true - "@esbuild/linux-mips64el@0.27.4": + '@esbuild/linux-mips64el@0.27.4': optional: true - "@esbuild/linux-ppc64@0.27.4": + '@esbuild/linux-ppc64@0.27.4': optional: true - "@esbuild/linux-riscv64@0.27.4": + '@esbuild/linux-riscv64@0.27.4': optional: true - "@esbuild/linux-s390x@0.27.4": + '@esbuild/linux-s390x@0.27.4': optional: true - "@esbuild/linux-x64@0.27.4": + '@esbuild/linux-x64@0.27.4': optional: true - "@esbuild/netbsd-arm64@0.27.4": + '@esbuild/netbsd-arm64@0.27.4': optional: true - "@esbuild/netbsd-x64@0.27.4": + '@esbuild/netbsd-x64@0.27.4': optional: true - "@esbuild/openbsd-arm64@0.27.4": + '@esbuild/openbsd-arm64@0.27.4': optional: true - "@esbuild/openbsd-x64@0.27.4": + '@esbuild/openbsd-x64@0.27.4': optional: true - "@esbuild/openharmony-arm64@0.27.4": + '@esbuild/openharmony-arm64@0.27.4': optional: true - "@esbuild/sunos-x64@0.27.4": + '@esbuild/sunos-x64@0.27.4': optional: true - "@esbuild/win32-arm64@0.27.4": + '@esbuild/win32-arm64@0.27.4': optional: true - "@esbuild/win32-ia32@0.27.4": + '@esbuild/win32-ia32@0.27.4': optional: true - "@esbuild/win32-x64@0.27.4": + '@esbuild/win32-x64@0.27.4': optional: true - "@iconify-json/simple-icons@1.2.74": + '@iconify-json/simple-icons@1.2.74': dependencies: - "@iconify/types": 2.0.0 + '@iconify/types': 2.0.0 - "@iconify/types@2.0.0": {} + '@iconify/types@2.0.0': {} - "@isaacs/balanced-match@4.0.1": {} + '@isaacs/balanced-match@4.0.1': {} - "@isaacs/brace-expansion@5.0.0": + '@isaacs/brace-expansion@5.0.0': dependencies: - "@isaacs/balanced-match": 4.0.1 + '@isaacs/balanced-match': 4.0.1 - "@isaacs/cliui@8.0.2": + '@isaacs/cliui@8.0.2': dependencies: string-width: 5.1.2 string-width-cjs: string-width@4.2.3 @@ -1639,239 +1045,239 @@ snapshots: wrap-ansi: 8.1.0 wrap-ansi-cjs: wrap-ansi@7.0.0 - "@jridgewell/sourcemap-codec@1.5.5": {} + '@jridgewell/sourcemap-codec@1.5.5': {} - "@rolldown/pluginutils@1.0.0-rc.2": {} + '@rolldown/pluginutils@1.0.0-rc.2': {} - "@rollup/rollup-android-arm-eabi@4.59.0": + '@rollup/rollup-android-arm-eabi@4.59.0': optional: true - "@rollup/rollup-android-arm64@4.59.0": + '@rollup/rollup-android-arm64@4.59.0': optional: true - "@rollup/rollup-darwin-arm64@4.59.0": + '@rollup/rollup-darwin-arm64@4.59.0': optional: true - "@rollup/rollup-darwin-x64@4.59.0": + '@rollup/rollup-darwin-x64@4.59.0': optional: true - "@rollup/rollup-freebsd-arm64@4.59.0": + '@rollup/rollup-freebsd-arm64@4.59.0': optional: true - "@rollup/rollup-freebsd-x64@4.59.0": + '@rollup/rollup-freebsd-x64@4.59.0': optional: true - "@rollup/rollup-linux-arm-gnueabihf@4.59.0": + '@rollup/rollup-linux-arm-gnueabihf@4.59.0': optional: true - "@rollup/rollup-linux-arm-musleabihf@4.59.0": + '@rollup/rollup-linux-arm-musleabihf@4.59.0': optional: true - "@rollup/rollup-linux-arm64-gnu@4.59.0": + '@rollup/rollup-linux-arm64-gnu@4.59.0': optional: true - "@rollup/rollup-linux-arm64-musl@4.59.0": + '@rollup/rollup-linux-arm64-musl@4.59.0': optional: true - "@rollup/rollup-linux-loong64-gnu@4.59.0": + '@rollup/rollup-linux-loong64-gnu@4.59.0': optional: true - "@rollup/rollup-linux-loong64-musl@4.59.0": + '@rollup/rollup-linux-loong64-musl@4.59.0': optional: true - "@rollup/rollup-linux-ppc64-gnu@4.59.0": + '@rollup/rollup-linux-ppc64-gnu@4.59.0': optional: true - "@rollup/rollup-linux-ppc64-musl@4.59.0": + '@rollup/rollup-linux-ppc64-musl@4.59.0': optional: true - "@rollup/rollup-linux-riscv64-gnu@4.59.0": + '@rollup/rollup-linux-riscv64-gnu@4.59.0': optional: true - "@rollup/rollup-linux-riscv64-musl@4.59.0": + '@rollup/rollup-linux-riscv64-musl@4.59.0': optional: true - "@rollup/rollup-linux-s390x-gnu@4.59.0": + '@rollup/rollup-linux-s390x-gnu@4.59.0': optional: true - "@rollup/rollup-linux-x64-gnu@4.59.0": + '@rollup/rollup-linux-x64-gnu@4.59.0': optional: true - "@rollup/rollup-linux-x64-musl@4.59.0": + '@rollup/rollup-linux-x64-musl@4.59.0': optional: true - "@rollup/rollup-openbsd-x64@4.59.0": + '@rollup/rollup-openbsd-x64@4.59.0': optional: true - "@rollup/rollup-openharmony-arm64@4.59.0": + '@rollup/rollup-openharmony-arm64@4.59.0': optional: true - "@rollup/rollup-win32-arm64-msvc@4.59.0": + '@rollup/rollup-win32-arm64-msvc@4.59.0': optional: true - "@rollup/rollup-win32-ia32-msvc@4.59.0": + '@rollup/rollup-win32-ia32-msvc@4.59.0': optional: true - "@rollup/rollup-win32-x64-gnu@4.59.0": + '@rollup/rollup-win32-x64-gnu@4.59.0': optional: true - "@rollup/rollup-win32-x64-msvc@4.59.0": + '@rollup/rollup-win32-x64-msvc@4.59.0': optional: true - "@shikijs/core@3.23.0": + '@shikijs/core@3.23.0': dependencies: - "@shikijs/types": 3.23.0 - "@shikijs/vscode-textmate": 10.0.2 - "@types/hast": 3.0.4 + '@shikijs/types': 3.23.0 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 hast-util-to-html: 9.0.5 - "@shikijs/engine-javascript@3.23.0": + '@shikijs/engine-javascript@3.23.0': dependencies: - "@shikijs/types": 3.23.0 - "@shikijs/vscode-textmate": 10.0.2 + '@shikijs/types': 3.23.0 + '@shikijs/vscode-textmate': 10.0.2 oniguruma-to-es: 4.3.5 - "@shikijs/engine-oniguruma@3.23.0": + '@shikijs/engine-oniguruma@3.23.0': dependencies: - "@shikijs/types": 3.23.0 - "@shikijs/vscode-textmate": 10.0.2 + '@shikijs/types': 3.23.0 + '@shikijs/vscode-textmate': 10.0.2 - "@shikijs/langs@3.23.0": + '@shikijs/langs@3.23.0': dependencies: - "@shikijs/types": 3.23.0 + '@shikijs/types': 3.23.0 - "@shikijs/themes@3.23.0": + '@shikijs/themes@3.23.0': dependencies: - "@shikijs/types": 3.23.0 + '@shikijs/types': 3.23.0 - "@shikijs/transformers@3.23.0": + '@shikijs/transformers@3.23.0': dependencies: - "@shikijs/core": 3.23.0 - "@shikijs/types": 3.23.0 + '@shikijs/core': 3.23.0 + '@shikijs/types': 3.23.0 - "@shikijs/types@3.23.0": + '@shikijs/types@3.23.0': dependencies: - "@shikijs/vscode-textmate": 10.0.2 - "@types/hast": 3.0.4 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 - "@shikijs/vscode-textmate@10.0.2": {} + '@shikijs/vscode-textmate@10.0.2': {} - "@types/estree@1.0.8": {} + '@types/estree@1.0.8': {} - "@types/hast@3.0.4": + '@types/hast@3.0.4': dependencies: - "@types/unist": 3.0.3 + '@types/unist': 3.0.3 - "@types/linkify-it@5.0.0": {} + '@types/linkify-it@5.0.0': {} - "@types/markdown-it@14.1.2": + '@types/markdown-it@14.1.2': dependencies: - "@types/linkify-it": 5.0.0 - "@types/mdurl": 2.0.0 + '@types/linkify-it': 5.0.0 + '@types/mdurl': 2.0.0 - "@types/mdast@4.0.4": + '@types/mdast@4.0.4': dependencies: - "@types/unist": 3.0.3 + '@types/unist': 3.0.3 - "@types/mdurl@2.0.0": {} + '@types/mdurl@2.0.0': {} - "@types/unist@3.0.3": {} + '@types/unist@3.0.3': {} - "@types/web-bluetooth@0.0.21": {} + '@types/web-bluetooth@0.0.21': {} - "@ungap/structured-clone@1.3.0": {} + '@ungap/structured-clone@1.3.0': {} - "@vitejs/plugin-vue@6.0.5(vite@7.3.1)(vue@3.5.30)": + '@vitejs/plugin-vue@6.0.5(vite@7.3.1)(vue@3.5.30)': dependencies: - "@rolldown/pluginutils": 1.0.0-rc.2 + '@rolldown/pluginutils': 1.0.0-rc.2 vite: 7.3.1 vue: 3.5.30 - "@vue/compiler-core@3.5.30": + '@vue/compiler-core@3.5.30': dependencies: - "@babel/parser": 7.29.0 - "@vue/shared": 3.5.30 + '@babel/parser': 7.29.0 + '@vue/shared': 3.5.30 entities: 7.0.1 estree-walker: 2.0.2 source-map-js: 1.2.1 - "@vue/compiler-dom@3.5.30": + '@vue/compiler-dom@3.5.30': dependencies: - "@vue/compiler-core": 3.5.30 - "@vue/shared": 3.5.30 + '@vue/compiler-core': 3.5.30 + '@vue/shared': 3.5.30 - "@vue/compiler-sfc@3.5.30": + '@vue/compiler-sfc@3.5.30': dependencies: - "@babel/parser": 7.29.0 - "@vue/compiler-core": 3.5.30 - "@vue/compiler-dom": 3.5.30 - "@vue/compiler-ssr": 3.5.30 - "@vue/shared": 3.5.30 + '@babel/parser': 7.29.0 + '@vue/compiler-core': 3.5.30 + '@vue/compiler-dom': 3.5.30 + '@vue/compiler-ssr': 3.5.30 + '@vue/shared': 3.5.30 estree-walker: 2.0.2 magic-string: 0.30.21 postcss: 8.5.8 source-map-js: 1.2.1 - "@vue/compiler-ssr@3.5.30": + '@vue/compiler-ssr@3.5.30': dependencies: - "@vue/compiler-dom": 3.5.30 - "@vue/shared": 3.5.30 + '@vue/compiler-dom': 3.5.30 + '@vue/shared': 3.5.30 - "@vue/devtools-api@8.1.0": + '@vue/devtools-api@8.1.0': dependencies: - "@vue/devtools-kit": 8.1.0 + '@vue/devtools-kit': 8.1.0 - "@vue/devtools-kit@8.1.0": + '@vue/devtools-kit@8.1.0': dependencies: - "@vue/devtools-shared": 8.1.0 + '@vue/devtools-shared': 8.1.0 birpc: 2.9.0 hookable: 5.5.3 perfect-debounce: 2.1.0 - "@vue/devtools-shared@8.1.0": {} + '@vue/devtools-shared@8.1.0': {} - "@vue/reactivity@3.5.30": + '@vue/reactivity@3.5.30': dependencies: - "@vue/shared": 3.5.30 + '@vue/shared': 3.5.30 - "@vue/runtime-core@3.5.30": + '@vue/runtime-core@3.5.30': dependencies: - "@vue/reactivity": 3.5.30 - "@vue/shared": 3.5.30 + '@vue/reactivity': 3.5.30 + '@vue/shared': 3.5.30 - "@vue/runtime-dom@3.5.30": + '@vue/runtime-dom@3.5.30': dependencies: - "@vue/reactivity": 3.5.30 - "@vue/runtime-core": 3.5.30 - "@vue/shared": 3.5.30 + '@vue/reactivity': 3.5.30 + '@vue/runtime-core': 3.5.30 + '@vue/shared': 3.5.30 csstype: 3.2.3 - "@vue/server-renderer@3.5.30(vue@3.5.30)": + '@vue/server-renderer@3.5.30(vue@3.5.30)': dependencies: - "@vue/compiler-ssr": 3.5.30 - "@vue/shared": 3.5.30 + '@vue/compiler-ssr': 3.5.30 + '@vue/shared': 3.5.30 vue: 3.5.30 - "@vue/shared@3.5.30": {} + '@vue/shared@3.5.30': {} - "@vueuse/core@14.2.1(vue@3.5.30)": + '@vueuse/core@14.2.1(vue@3.5.30)': dependencies: - "@types/web-bluetooth": 0.0.21 - "@vueuse/metadata": 14.2.1 - "@vueuse/shared": 14.2.1(vue@3.5.30) + '@types/web-bluetooth': 0.0.21 + '@vueuse/metadata': 14.2.1 + '@vueuse/shared': 14.2.1(vue@3.5.30) vue: 3.5.30 - "@vueuse/integrations@14.2.1(focus-trap@7.8.0)(vue@3.5.30)": + '@vueuse/integrations@14.2.1(focus-trap@7.8.0)(vue@3.5.30)': dependencies: - "@vueuse/core": 14.2.1(vue@3.5.30) - "@vueuse/shared": 14.2.1(vue@3.5.30) + '@vueuse/core': 14.2.1(vue@3.5.30) + '@vueuse/shared': 14.2.1(vue@3.5.30) vue: 3.5.30 optionalDependencies: focus-trap: 7.8.0 - "@vueuse/metadata@14.2.1": {} + '@vueuse/metadata@14.2.1': {} - "@vueuse/shared@14.2.1(vue@3.5.30)": + '@vueuse/shared@14.2.1(vue@3.5.30)': dependencies: vue: 3.5.30 @@ -1929,32 +1335,32 @@ snapshots: esbuild@0.27.4: optionalDependencies: - "@esbuild/aix-ppc64": 0.27.4 - "@esbuild/android-arm": 0.27.4 - "@esbuild/android-arm64": 0.27.4 - "@esbuild/android-x64": 0.27.4 - "@esbuild/darwin-arm64": 0.27.4 - "@esbuild/darwin-x64": 0.27.4 - "@esbuild/freebsd-arm64": 0.27.4 - "@esbuild/freebsd-x64": 0.27.4 - "@esbuild/linux-arm": 0.27.4 - "@esbuild/linux-arm64": 0.27.4 - "@esbuild/linux-ia32": 0.27.4 - "@esbuild/linux-loong64": 0.27.4 - "@esbuild/linux-mips64el": 0.27.4 - "@esbuild/linux-ppc64": 0.27.4 - "@esbuild/linux-riscv64": 0.27.4 - "@esbuild/linux-s390x": 0.27.4 - "@esbuild/linux-x64": 0.27.4 - "@esbuild/netbsd-arm64": 0.27.4 - "@esbuild/netbsd-x64": 0.27.4 - "@esbuild/openbsd-arm64": 0.27.4 - "@esbuild/openbsd-x64": 0.27.4 - "@esbuild/openharmony-arm64": 0.27.4 - "@esbuild/sunos-x64": 0.27.4 - "@esbuild/win32-arm64": 0.27.4 - "@esbuild/win32-ia32": 0.27.4 - "@esbuild/win32-x64": 0.27.4 + '@esbuild/aix-ppc64': 0.27.4 + '@esbuild/android-arm': 0.27.4 + '@esbuild/android-arm64': 0.27.4 + '@esbuild/android-x64': 0.27.4 + '@esbuild/darwin-arm64': 0.27.4 + '@esbuild/darwin-x64': 0.27.4 + '@esbuild/freebsd-arm64': 0.27.4 + '@esbuild/freebsd-x64': 0.27.4 + '@esbuild/linux-arm': 0.27.4 + '@esbuild/linux-arm64': 0.27.4 + '@esbuild/linux-ia32': 0.27.4 + '@esbuild/linux-loong64': 0.27.4 + '@esbuild/linux-mips64el': 0.27.4 + '@esbuild/linux-ppc64': 0.27.4 + '@esbuild/linux-riscv64': 0.27.4 + '@esbuild/linux-s390x': 0.27.4 + '@esbuild/linux-x64': 0.27.4 + '@esbuild/netbsd-arm64': 0.27.4 + '@esbuild/netbsd-x64': 0.27.4 + '@esbuild/openbsd-arm64': 0.27.4 + '@esbuild/openbsd-x64': 0.27.4 + '@esbuild/openharmony-arm64': 0.27.4 + '@esbuild/sunos-x64': 0.27.4 + '@esbuild/win32-arm64': 0.27.4 + '@esbuild/win32-ia32': 0.27.4 + '@esbuild/win32-x64': 0.27.4 esprima@4.0.1: {} @@ -1998,8 +1404,8 @@ snapshots: hast-util-to-html@9.0.5: dependencies: - "@types/hast": 3.0.4 - "@types/unist": 3.0.3 + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 ccount: 2.0.1 comma-separated-tokens: 2.0.3 hast-util-whitespace: 3.0.0 @@ -2012,7 +1418,7 @@ snapshots: hast-util-whitespace@3.0.0: dependencies: - "@types/hast": 3.0.4 + '@types/hast': 3.0.4 hookable@5.5.3: {} @@ -2026,7 +1432,7 @@ snapshots: jackspeak@4.1.1: dependencies: - "@isaacs/cliui": 8.0.2 + '@isaacs/cliui': 8.0.2 js-yaml@3.14.2: dependencies: @@ -2039,15 +1445,15 @@ snapshots: magic-string@0.30.21: dependencies: - "@jridgewell/sourcemap-codec": 1.5.5 + '@jridgewell/sourcemap-codec': 1.5.5 mark.js@8.11.1: {} mdast-util-to-hast@13.2.1: dependencies: - "@types/hast": 3.0.4 - "@types/mdast": 4.0.4 - "@ungap/structured-clone": 1.3.0 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@ungap/structured-clone': 1.3.0 devlop: 1.1.0 micromark-util-sanitize-uri: 2.0.1 trim-lines: 3.0.1 @@ -2074,7 +1480,7 @@ snapshots: minimatch@10.1.1: dependencies: - "@isaacs/brace-expansion": 5.0.0 + '@isaacs/brace-expansion': 5.0.0 minipass@7.1.2: {} @@ -2127,33 +1533,33 @@ snapshots: rollup@4.59.0: dependencies: - "@types/estree": 1.0.8 + '@types/estree': 1.0.8 optionalDependencies: - "@rollup/rollup-android-arm-eabi": 4.59.0 - "@rollup/rollup-android-arm64": 4.59.0 - "@rollup/rollup-darwin-arm64": 4.59.0 - "@rollup/rollup-darwin-x64": 4.59.0 - "@rollup/rollup-freebsd-arm64": 4.59.0 - "@rollup/rollup-freebsd-x64": 4.59.0 - "@rollup/rollup-linux-arm-gnueabihf": 4.59.0 - "@rollup/rollup-linux-arm-musleabihf": 4.59.0 - "@rollup/rollup-linux-arm64-gnu": 4.59.0 - "@rollup/rollup-linux-arm64-musl": 4.59.0 - "@rollup/rollup-linux-loong64-gnu": 4.59.0 - "@rollup/rollup-linux-loong64-musl": 4.59.0 - "@rollup/rollup-linux-ppc64-gnu": 4.59.0 - "@rollup/rollup-linux-ppc64-musl": 4.59.0 - "@rollup/rollup-linux-riscv64-gnu": 4.59.0 - "@rollup/rollup-linux-riscv64-musl": 4.59.0 - "@rollup/rollup-linux-s390x-gnu": 4.59.0 - "@rollup/rollup-linux-x64-gnu": 4.59.0 - "@rollup/rollup-linux-x64-musl": 4.59.0 - "@rollup/rollup-openbsd-x64": 4.59.0 - "@rollup/rollup-openharmony-arm64": 4.59.0 - "@rollup/rollup-win32-arm64-msvc": 4.59.0 - "@rollup/rollup-win32-ia32-msvc": 4.59.0 - "@rollup/rollup-win32-x64-gnu": 4.59.0 - "@rollup/rollup-win32-x64-msvc": 4.59.0 + '@rollup/rollup-android-arm-eabi': 4.59.0 + '@rollup/rollup-android-arm64': 4.59.0 + '@rollup/rollup-darwin-arm64': 4.59.0 + '@rollup/rollup-darwin-x64': 4.59.0 + '@rollup/rollup-freebsd-arm64': 4.59.0 + '@rollup/rollup-freebsd-x64': 4.59.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.59.0 + '@rollup/rollup-linux-arm-musleabihf': 4.59.0 + '@rollup/rollup-linux-arm64-gnu': 4.59.0 + '@rollup/rollup-linux-arm64-musl': 4.59.0 + '@rollup/rollup-linux-loong64-gnu': 4.59.0 + '@rollup/rollup-linux-loong64-musl': 4.59.0 + '@rollup/rollup-linux-ppc64-gnu': 4.59.0 + '@rollup/rollup-linux-ppc64-musl': 4.59.0 + '@rollup/rollup-linux-riscv64-gnu': 4.59.0 + '@rollup/rollup-linux-riscv64-musl': 4.59.0 + '@rollup/rollup-linux-s390x-gnu': 4.59.0 + '@rollup/rollup-linux-x64-gnu': 4.59.0 + '@rollup/rollup-linux-x64-musl': 4.59.0 + '@rollup/rollup-openbsd-x64': 4.59.0 + '@rollup/rollup-openharmony-arm64': 4.59.0 + '@rollup/rollup-win32-arm64-msvc': 4.59.0 + '@rollup/rollup-win32-ia32-msvc': 4.59.0 + '@rollup/rollup-win32-x64-gnu': 4.59.0 + '@rollup/rollup-win32-x64-msvc': 4.59.0 fsevents: 2.3.3 section-matter@1.0.0: @@ -2169,14 +1575,14 @@ snapshots: shiki@3.23.0: dependencies: - "@shikijs/core": 3.23.0 - "@shikijs/engine-javascript": 3.23.0 - "@shikijs/engine-oniguruma": 3.23.0 - "@shikijs/langs": 3.23.0 - "@shikijs/themes": 3.23.0 - "@shikijs/types": 3.23.0 - "@shikijs/vscode-textmate": 10.0.2 - "@types/hast": 3.0.4 + '@shikijs/core': 3.23.0 + '@shikijs/engine-javascript': 3.23.0 + '@shikijs/engine-oniguruma': 3.23.0 + '@shikijs/langs': 3.23.0 + '@shikijs/themes': 3.23.0 + '@shikijs/types': 3.23.0 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 signal-exit@4.1.0: {} @@ -2224,35 +1630,35 @@ snapshots: unist-util-is@6.0.1: dependencies: - "@types/unist": 3.0.3 + '@types/unist': 3.0.3 unist-util-position@5.0.0: dependencies: - "@types/unist": 3.0.3 + '@types/unist': 3.0.3 unist-util-stringify-position@4.0.0: dependencies: - "@types/unist": 3.0.3 + '@types/unist': 3.0.3 unist-util-visit-parents@6.0.2: dependencies: - "@types/unist": 3.0.3 + '@types/unist': 3.0.3 unist-util-is: 6.0.1 unist-util-visit@5.1.0: dependencies: - "@types/unist": 3.0.3 + '@types/unist': 3.0.3 unist-util-is: 6.0.1 unist-util-visit-parents: 6.0.2 vfile-message@4.0.3: dependencies: - "@types/unist": 3.0.3 + '@types/unist': 3.0.3 unist-util-stringify-position: 4.0.0 vfile@6.0.3: dependencies: - "@types/unist": 3.0.3 + '@types/unist': 3.0.3 vfile-message: 4.0.3 vite@7.3.1: @@ -2274,19 +1680,19 @@ snapshots: vitepress@2.0.0-alpha.16(postcss@8.5.8): dependencies: - "@docsearch/css": 4.6.0 - "@docsearch/js": 4.6.0 - "@docsearch/sidepanel-js": 4.6.0 - "@iconify-json/simple-icons": 1.2.74 - "@shikijs/core": 3.23.0 - "@shikijs/transformers": 3.23.0 - "@shikijs/types": 3.23.0 - "@types/markdown-it": 14.1.2 - "@vitejs/plugin-vue": 6.0.5(vite@7.3.1)(vue@3.5.30) - "@vue/devtools-api": 8.1.0 - "@vue/shared": 3.5.30 - "@vueuse/core": 14.2.1(vue@3.5.30) - "@vueuse/integrations": 14.2.1(focus-trap@7.8.0)(vue@3.5.30) + '@docsearch/css': 4.6.0 + '@docsearch/js': 4.6.0 + '@docsearch/sidepanel-js': 4.6.0 + '@iconify-json/simple-icons': 1.2.74 + '@shikijs/core': 3.23.0 + '@shikijs/transformers': 3.23.0 + '@shikijs/types': 3.23.0 + '@types/markdown-it': 14.1.2 + '@vitejs/plugin-vue': 6.0.5(vite@7.3.1)(vue@3.5.30) + '@vue/devtools-api': 8.1.0 + '@vue/shared': 3.5.30 + '@vueuse/core': 14.2.1(vue@3.5.30) + '@vueuse/integrations': 14.2.1(focus-trap@7.8.0)(vue@3.5.30) focus-trap: 7.8.0 mark.js: 8.11.1 minisearch: 7.2.0 @@ -2296,7 +1702,7 @@ snapshots: optionalDependencies: postcss: 8.5.8 transitivePeerDependencies: - - "@types/node" + - '@types/node' - async-validator - axios - change-case @@ -2322,11 +1728,11 @@ snapshots: vue@3.5.30: dependencies: - "@vue/compiler-dom": 3.5.30 - "@vue/compiler-sfc": 3.5.30 - "@vue/runtime-dom": 3.5.30 - "@vue/server-renderer": 3.5.30(vue@3.5.30) - "@vue/shared": 3.5.30 + '@vue/compiler-dom': 3.5.30 + '@vue/compiler-sfc': 3.5.30 + '@vue/runtime-dom': 3.5.30 + '@vue/server-renderer': 3.5.30(vue@3.5.30) + '@vue/shared': 3.5.30 which@2.0.2: dependencies: From 625480da64329aa24037e07923245778b13b9c6a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 19 Mar 2026 11:02:18 +0000 Subject: [PATCH 174/279] chore(deps): bump minimatch from 10.1.1 to 10.2.4 in /docs Bumps [minimatch](https://github.com/isaacs/minimatch) from 10.1.1 to 10.2.4. - [Changelog](https://github.com/isaacs/minimatch/blob/main/changelog.md) - [Commits](https://github.com/isaacs/minimatch/compare/v10.1.1...v10.2.4) --- updated-dependencies: - dependency-name: minimatch dependency-version: 10.2.4 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- docs/pnpm-lock.yaml | 1856 +++++++++++++++---------------------------- 1 file changed, 631 insertions(+), 1225 deletions(-) diff --git a/docs/pnpm-lock.yaml b/docs/pnpm-lock.yaml index 7497803e..7dbba065 100644 --- a/docs/pnpm-lock.yaml +++ b/docs/pnpm-lock.yaml @@ -1,10 +1,11 @@ -lockfileVersion: "9.0" +lockfileVersion: '9.0' settings: autoInstallPeers: true excludeLinksFromLockfile: false importers: + .: devDependencies: vitepress: @@ -15,744 +16,454 @@ importers: version: 1.33.1 packages: - "@babel/helper-string-parser@7.27.1": - resolution: - { - integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==, - } - engines: { node: ">=6.9.0" } - "@babel/helper-validator-identifier@7.28.5": - resolution: - { - integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==, - } - engines: { node: ">=6.9.0" } + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} + engines: {node: '>=6.9.0'} - "@babel/parser@7.29.0": - resolution: - { - integrity: sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==, - } - engines: { node: ">=6.0.0" } + '@babel/helper-validator-identifier@7.28.5': + resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.29.0': + resolution: {integrity: sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==} + engines: {node: '>=6.0.0'} hasBin: true - "@babel/types@7.29.0": - resolution: - { - integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==, - } - engines: { node: ">=6.9.0" } + '@babel/types@7.29.0': + resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} + engines: {node: '>=6.9.0'} - "@docsearch/css@4.6.0": - resolution: - { - integrity: sha512-YlcAimkXclvqta47g47efzCM5CFxDwv2ClkDfEs/fC/Ak0OxPH2b3czwa4o8O1TRBf+ujFF2RiUwszz2fPVNJQ==, - } + '@docsearch/css@4.6.0': + resolution: {integrity: sha512-YlcAimkXclvqta47g47efzCM5CFxDwv2ClkDfEs/fC/Ak0OxPH2b3czwa4o8O1TRBf+ujFF2RiUwszz2fPVNJQ==} - "@docsearch/js@4.6.0": - resolution: - { - integrity: sha512-9/rbgkm/BgTq46cwxIohvSAz3koOFjnPpg0mwkJItAfzKbQIj+310PvwtgUY1YITDuGCag6yOL50GW2DBkaaBw==, - } + '@docsearch/js@4.6.0': + resolution: {integrity: sha512-9/rbgkm/BgTq46cwxIohvSAz3koOFjnPpg0mwkJItAfzKbQIj+310PvwtgUY1YITDuGCag6yOL50GW2DBkaaBw==} - "@docsearch/sidepanel-js@4.6.0": - resolution: - { - integrity: sha512-lFT5KLwlzUmpoGArCScNoK41l9a22JYsEPwBzMrz+/ILVR5Ax87UphCuiyDFQWEvEmbwzn/kJx5W/O5BUlN1Rw==, - } + '@docsearch/sidepanel-js@4.6.0': + resolution: {integrity: sha512-lFT5KLwlzUmpoGArCScNoK41l9a22JYsEPwBzMrz+/ILVR5Ax87UphCuiyDFQWEvEmbwzn/kJx5W/O5BUlN1Rw==} - "@esbuild/aix-ppc64@0.27.4": - resolution: - { - integrity: sha512-cQPwL2mp2nSmHHJlCyoXgHGhbEPMrEEU5xhkcy3Hs/O7nGZqEpZ2sUtLaL9MORLtDfRvVl2/3PAuEkYZH0Ty8Q==, - } - engines: { node: ">=18" } + '@esbuild/aix-ppc64@0.27.4': + resolution: {integrity: sha512-cQPwL2mp2nSmHHJlCyoXgHGhbEPMrEEU5xhkcy3Hs/O7nGZqEpZ2sUtLaL9MORLtDfRvVl2/3PAuEkYZH0Ty8Q==} + engines: {node: '>=18'} cpu: [ppc64] os: [aix] - "@esbuild/android-arm64@0.27.4": - resolution: - { - integrity: sha512-gdLscB7v75wRfu7QSm/zg6Rx29VLdy9eTr2t44sfTW7CxwAtQghZ4ZnqHk3/ogz7xao0QAgrkradbBzcqFPasw==, - } - engines: { node: ">=18" } + '@esbuild/android-arm64@0.27.4': + resolution: {integrity: sha512-gdLscB7v75wRfu7QSm/zg6Rx29VLdy9eTr2t44sfTW7CxwAtQghZ4ZnqHk3/ogz7xao0QAgrkradbBzcqFPasw==} + engines: {node: '>=18'} cpu: [arm64] os: [android] - "@esbuild/android-arm@0.27.4": - resolution: - { - integrity: sha512-X9bUgvxiC8CHAGKYufLIHGXPJWnr0OCdR0anD2e21vdvgCI8lIfqFbnoeOz7lBjdrAGUhqLZLcQo6MLhTO2DKQ==, - } - engines: { node: ">=18" } + '@esbuild/android-arm@0.27.4': + resolution: {integrity: sha512-X9bUgvxiC8CHAGKYufLIHGXPJWnr0OCdR0anD2e21vdvgCI8lIfqFbnoeOz7lBjdrAGUhqLZLcQo6MLhTO2DKQ==} + engines: {node: '>=18'} cpu: [arm] os: [android] - "@esbuild/android-x64@0.27.4": - resolution: - { - integrity: sha512-PzPFnBNVF292sfpfhiyiXCGSn9HZg5BcAz+ivBuSsl6Rk4ga1oEXAamhOXRFyMcjwr2DVtm40G65N3GLeH1Lvw==, - } - engines: { node: ">=18" } + '@esbuild/android-x64@0.27.4': + resolution: {integrity: sha512-PzPFnBNVF292sfpfhiyiXCGSn9HZg5BcAz+ivBuSsl6Rk4ga1oEXAamhOXRFyMcjwr2DVtm40G65N3GLeH1Lvw==} + engines: {node: '>=18'} cpu: [x64] os: [android] - "@esbuild/darwin-arm64@0.27.4": - resolution: - { - integrity: sha512-b7xaGIwdJlht8ZFCvMkpDN6uiSmnxxK56N2GDTMYPr2/gzvfdQN8rTfBsvVKmIVY/X7EM+/hJKEIbbHs9oA4tQ==, - } - engines: { node: ">=18" } + '@esbuild/darwin-arm64@0.27.4': + resolution: {integrity: sha512-b7xaGIwdJlht8ZFCvMkpDN6uiSmnxxK56N2GDTMYPr2/gzvfdQN8rTfBsvVKmIVY/X7EM+/hJKEIbbHs9oA4tQ==} + engines: {node: '>=18'} cpu: [arm64] os: [darwin] - "@esbuild/darwin-x64@0.27.4": - resolution: - { - integrity: sha512-sR+OiKLwd15nmCdqpXMnuJ9W2kpy0KigzqScqHI3Hqwr7IXxBp3Yva+yJwoqh7rE8V77tdoheRYataNKL4QrPw==, - } - engines: { node: ">=18" } + '@esbuild/darwin-x64@0.27.4': + resolution: {integrity: sha512-sR+OiKLwd15nmCdqpXMnuJ9W2kpy0KigzqScqHI3Hqwr7IXxBp3Yva+yJwoqh7rE8V77tdoheRYataNKL4QrPw==} + engines: {node: '>=18'} cpu: [x64] os: [darwin] - "@esbuild/freebsd-arm64@0.27.4": - resolution: - { - integrity: sha512-jnfpKe+p79tCnm4GVav68A7tUFeKQwQyLgESwEAUzyxk/TJr4QdGog9sqWNcUbr/bZt/O/HXouspuQDd9JxFSw==, - } - engines: { node: ">=18" } + '@esbuild/freebsd-arm64@0.27.4': + resolution: {integrity: sha512-jnfpKe+p79tCnm4GVav68A7tUFeKQwQyLgESwEAUzyxk/TJr4QdGog9sqWNcUbr/bZt/O/HXouspuQDd9JxFSw==} + engines: {node: '>=18'} cpu: [arm64] os: [freebsd] - "@esbuild/freebsd-x64@0.27.4": - resolution: - { - integrity: sha512-2kb4ceA/CpfUrIcTUl1wrP/9ad9Atrp5J94Lq69w7UwOMolPIGrfLSvAKJp0RTvkPPyn6CIWrNy13kyLikZRZQ==, - } - engines: { node: ">=18" } + '@esbuild/freebsd-x64@0.27.4': + resolution: {integrity: sha512-2kb4ceA/CpfUrIcTUl1wrP/9ad9Atrp5J94Lq69w7UwOMolPIGrfLSvAKJp0RTvkPPyn6CIWrNy13kyLikZRZQ==} + engines: {node: '>=18'} cpu: [x64] os: [freebsd] - "@esbuild/linux-arm64@0.27.4": - resolution: - { - integrity: sha512-7nQOttdzVGth1iz57kxg9uCz57dxQLHWxopL6mYuYthohPKEK0vU0C3O21CcBK6KDlkYVcnDXY099HcCDXd9dA==, - } - engines: { node: ">=18" } + '@esbuild/linux-arm64@0.27.4': + resolution: {integrity: sha512-7nQOttdzVGth1iz57kxg9uCz57dxQLHWxopL6mYuYthohPKEK0vU0C3O21CcBK6KDlkYVcnDXY099HcCDXd9dA==} + engines: {node: '>=18'} cpu: [arm64] os: [linux] - "@esbuild/linux-arm@0.27.4": - resolution: - { - integrity: sha512-aBYgcIxX/wd5n2ys0yESGeYMGF+pv6g0DhZr3G1ZG4jMfruU9Tl1i2Z+Wnj9/KjGz1lTLCcorqE2viePZqj4Eg==, - } - engines: { node: ">=18" } + '@esbuild/linux-arm@0.27.4': + resolution: {integrity: sha512-aBYgcIxX/wd5n2ys0yESGeYMGF+pv6g0DhZr3G1ZG4jMfruU9Tl1i2Z+Wnj9/KjGz1lTLCcorqE2viePZqj4Eg==} + engines: {node: '>=18'} cpu: [arm] os: [linux] - "@esbuild/linux-ia32@0.27.4": - resolution: - { - integrity: sha512-oPtixtAIzgvzYcKBQM/qZ3R+9TEUd1aNJQu0HhGyqtx6oS7qTpvjheIWBbes4+qu1bNlo2V4cbkISr8q6gRBFA==, - } - engines: { node: ">=18" } + '@esbuild/linux-ia32@0.27.4': + resolution: {integrity: sha512-oPtixtAIzgvzYcKBQM/qZ3R+9TEUd1aNJQu0HhGyqtx6oS7qTpvjheIWBbes4+qu1bNlo2V4cbkISr8q6gRBFA==} + engines: {node: '>=18'} cpu: [ia32] os: [linux] - "@esbuild/linux-loong64@0.27.4": - resolution: - { - integrity: sha512-8mL/vh8qeCoRcFH2nM8wm5uJP+ZcVYGGayMavi8GmRJjuI3g1v6Z7Ni0JJKAJW+m0EtUuARb6Lmp4hMjzCBWzA==, - } - engines: { node: ">=18" } + '@esbuild/linux-loong64@0.27.4': + resolution: {integrity: sha512-8mL/vh8qeCoRcFH2nM8wm5uJP+ZcVYGGayMavi8GmRJjuI3g1v6Z7Ni0JJKAJW+m0EtUuARb6Lmp4hMjzCBWzA==} + engines: {node: '>=18'} cpu: [loong64] os: [linux] - "@esbuild/linux-mips64el@0.27.4": - resolution: - { - integrity: sha512-1RdrWFFiiLIW7LQq9Q2NES+HiD4NyT8Itj9AUeCl0IVCA459WnPhREKgwrpaIfTOe+/2rdntisegiPWn/r/aAw==, - } - engines: { node: ">=18" } + '@esbuild/linux-mips64el@0.27.4': + resolution: {integrity: sha512-1RdrWFFiiLIW7LQq9Q2NES+HiD4NyT8Itj9AUeCl0IVCA459WnPhREKgwrpaIfTOe+/2rdntisegiPWn/r/aAw==} + engines: {node: '>=18'} cpu: [mips64el] os: [linux] - "@esbuild/linux-ppc64@0.27.4": - resolution: - { - integrity: sha512-tLCwNG47l3sd9lpfyx9LAGEGItCUeRCWeAx6x2Jmbav65nAwoPXfewtAdtbtit/pJFLUWOhpv0FpS6GQAmPrHA==, - } - engines: { node: ">=18" } + '@esbuild/linux-ppc64@0.27.4': + resolution: {integrity: sha512-tLCwNG47l3sd9lpfyx9LAGEGItCUeRCWeAx6x2Jmbav65nAwoPXfewtAdtbtit/pJFLUWOhpv0FpS6GQAmPrHA==} + engines: {node: '>=18'} cpu: [ppc64] os: [linux] - "@esbuild/linux-riscv64@0.27.4": - resolution: - { - integrity: sha512-BnASypppbUWyqjd1KIpU4AUBiIhVr6YlHx/cnPgqEkNoVOhHg+YiSVxM1RLfiy4t9cAulbRGTNCKOcqHrEQLIw==, - } - engines: { node: ">=18" } + '@esbuild/linux-riscv64@0.27.4': + resolution: {integrity: sha512-BnASypppbUWyqjd1KIpU4AUBiIhVr6YlHx/cnPgqEkNoVOhHg+YiSVxM1RLfiy4t9cAulbRGTNCKOcqHrEQLIw==} + engines: {node: '>=18'} cpu: [riscv64] os: [linux] - "@esbuild/linux-s390x@0.27.4": - resolution: - { - integrity: sha512-+eUqgb/Z7vxVLezG8bVB9SfBie89gMueS+I0xYh2tJdw3vqA/0ImZJ2ROeWwVJN59ihBeZ7Tu92dF/5dy5FttA==, - } - engines: { node: ">=18" } + '@esbuild/linux-s390x@0.27.4': + resolution: {integrity: sha512-+eUqgb/Z7vxVLezG8bVB9SfBie89gMueS+I0xYh2tJdw3vqA/0ImZJ2ROeWwVJN59ihBeZ7Tu92dF/5dy5FttA==} + engines: {node: '>=18'} cpu: [s390x] os: [linux] - "@esbuild/linux-x64@0.27.4": - resolution: - { - integrity: sha512-S5qOXrKV8BQEzJPVxAwnryi2+Iq5pB40gTEIT69BQONqR7JH1EPIcQ/Uiv9mCnn05jff9umq/5nqzxlqTOg9NA==, - } - engines: { node: ">=18" } + '@esbuild/linux-x64@0.27.4': + resolution: {integrity: sha512-S5qOXrKV8BQEzJPVxAwnryi2+Iq5pB40gTEIT69BQONqR7JH1EPIcQ/Uiv9mCnn05jff9umq/5nqzxlqTOg9NA==} + engines: {node: '>=18'} cpu: [x64] os: [linux] - "@esbuild/netbsd-arm64@0.27.4": - resolution: - { - integrity: sha512-xHT8X4sb0GS8qTqiwzHqpY00C95DPAq7nAwX35Ie/s+LO9830hrMd3oX0ZMKLvy7vsonee73x0lmcdOVXFzd6Q==, - } - engines: { node: ">=18" } + '@esbuild/netbsd-arm64@0.27.4': + resolution: {integrity: sha512-xHT8X4sb0GS8qTqiwzHqpY00C95DPAq7nAwX35Ie/s+LO9830hrMd3oX0ZMKLvy7vsonee73x0lmcdOVXFzd6Q==} + engines: {node: '>=18'} cpu: [arm64] os: [netbsd] - "@esbuild/netbsd-x64@0.27.4": - resolution: - { - integrity: sha512-RugOvOdXfdyi5Tyv40kgQnI0byv66BFgAqjdgtAKqHoZTbTF2QqfQrFwa7cHEORJf6X2ht+l9ABLMP0dnKYsgg==, - } - engines: { node: ">=18" } + '@esbuild/netbsd-x64@0.27.4': + resolution: {integrity: sha512-RugOvOdXfdyi5Tyv40kgQnI0byv66BFgAqjdgtAKqHoZTbTF2QqfQrFwa7cHEORJf6X2ht+l9ABLMP0dnKYsgg==} + engines: {node: '>=18'} cpu: [x64] os: [netbsd] - "@esbuild/openbsd-arm64@0.27.4": - resolution: - { - integrity: sha512-2MyL3IAaTX+1/qP0O1SwskwcwCoOI4kV2IBX1xYnDDqthmq5ArrW94qSIKCAuRraMgPOmG0RDTA74mzYNQA9ow==, - } - engines: { node: ">=18" } + '@esbuild/openbsd-arm64@0.27.4': + resolution: {integrity: sha512-2MyL3IAaTX+1/qP0O1SwskwcwCoOI4kV2IBX1xYnDDqthmq5ArrW94qSIKCAuRraMgPOmG0RDTA74mzYNQA9ow==} + engines: {node: '>=18'} cpu: [arm64] os: [openbsd] - "@esbuild/openbsd-x64@0.27.4": - resolution: - { - integrity: sha512-u8fg/jQ5aQDfsnIV6+KwLOf1CmJnfu1ShpwqdwC0uA7ZPwFws55Ngc12vBdeUdnuWoQYx/SOQLGDcdlfXhYmXQ==, - } - engines: { node: ">=18" } + '@esbuild/openbsd-x64@0.27.4': + resolution: {integrity: sha512-u8fg/jQ5aQDfsnIV6+KwLOf1CmJnfu1ShpwqdwC0uA7ZPwFws55Ngc12vBdeUdnuWoQYx/SOQLGDcdlfXhYmXQ==} + engines: {node: '>=18'} cpu: [x64] os: [openbsd] - "@esbuild/openharmony-arm64@0.27.4": - resolution: - { - integrity: sha512-JkTZrl6VbyO8lDQO3yv26nNr2RM2yZzNrNHEsj9bm6dOwwu9OYN28CjzZkH57bh4w0I2F7IodpQvUAEd1mbWXg==, - } - engines: { node: ">=18" } + '@esbuild/openharmony-arm64@0.27.4': + resolution: {integrity: sha512-JkTZrl6VbyO8lDQO3yv26nNr2RM2yZzNrNHEsj9bm6dOwwu9OYN28CjzZkH57bh4w0I2F7IodpQvUAEd1mbWXg==} + engines: {node: '>=18'} cpu: [arm64] os: [openharmony] - "@esbuild/sunos-x64@0.27.4": - resolution: - { - integrity: sha512-/gOzgaewZJfeJTlsWhvUEmUG4tWEY2Spp5M20INYRg2ZKl9QPO3QEEgPeRtLjEWSW8FilRNacPOg8R1uaYkA6g==, - } - engines: { node: ">=18" } + '@esbuild/sunos-x64@0.27.4': + resolution: {integrity: sha512-/gOzgaewZJfeJTlsWhvUEmUG4tWEY2Spp5M20INYRg2ZKl9QPO3QEEgPeRtLjEWSW8FilRNacPOg8R1uaYkA6g==} + engines: {node: '>=18'} cpu: [x64] os: [sunos] - "@esbuild/win32-arm64@0.27.4": - resolution: - { - integrity: sha512-Z9SExBg2y32smoDQdf1HRwHRt6vAHLXcxD2uGgO/v2jK7Y718Ix4ndsbNMU/+1Qiem9OiOdaqitioZwxivhXYg==, - } - engines: { node: ">=18" } + '@esbuild/win32-arm64@0.27.4': + resolution: {integrity: sha512-Z9SExBg2y32smoDQdf1HRwHRt6vAHLXcxD2uGgO/v2jK7Y718Ix4ndsbNMU/+1Qiem9OiOdaqitioZwxivhXYg==} + engines: {node: '>=18'} cpu: [arm64] os: [win32] - "@esbuild/win32-ia32@0.27.4": - resolution: - { - integrity: sha512-DAyGLS0Jz5G5iixEbMHi5KdiApqHBWMGzTtMiJ72ZOLhbu/bzxgAe8Ue8CTS3n3HbIUHQz/L51yMdGMeoxXNJw==, - } - engines: { node: ">=18" } + '@esbuild/win32-ia32@0.27.4': + resolution: {integrity: sha512-DAyGLS0Jz5G5iixEbMHi5KdiApqHBWMGzTtMiJ72ZOLhbu/bzxgAe8Ue8CTS3n3HbIUHQz/L51yMdGMeoxXNJw==} + engines: {node: '>=18'} cpu: [ia32] os: [win32] - "@esbuild/win32-x64@0.27.4": - resolution: - { - integrity: sha512-+knoa0BDoeXgkNvvV1vvbZX4+hizelrkwmGJBdT17t8FNPwG2lKemmuMZlmaNQ3ws3DKKCxpb4zRZEIp3UxFCg==, - } - engines: { node: ">=18" } + '@esbuild/win32-x64@0.27.4': + resolution: {integrity: sha512-+knoa0BDoeXgkNvvV1vvbZX4+hizelrkwmGJBdT17t8FNPwG2lKemmuMZlmaNQ3ws3DKKCxpb4zRZEIp3UxFCg==} + engines: {node: '>=18'} cpu: [x64] os: [win32] - "@iconify-json/simple-icons@1.2.74": - resolution: - { - integrity: sha512-yqaohfY6jnYjTVpuTkaBQHrWbdUrQyWXhau0r/0EZiNWYXPX/P8WWwl1DoLH5CbvDjjcWQw5J0zADhgCUklOqA==, - } + '@iconify-json/simple-icons@1.2.74': + resolution: {integrity: sha512-yqaohfY6jnYjTVpuTkaBQHrWbdUrQyWXhau0r/0EZiNWYXPX/P8WWwl1DoLH5CbvDjjcWQw5J0zADhgCUklOqA==} - "@iconify/types@2.0.0": - resolution: - { - integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==, - } + '@iconify/types@2.0.0': + resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} - "@isaacs/balanced-match@4.0.1": - resolution: - { - integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==, - } - engines: { node: 20 || >=22 } + '@isaacs/balanced-match@4.0.1': + resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} + engines: {node: 20 || >=22} - "@isaacs/brace-expansion@5.0.0": - resolution: - { - integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==, - } - engines: { node: 20 || >=22 } + '@isaacs/brace-expansion@5.0.0': + resolution: {integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==} + engines: {node: 20 || >=22} - "@isaacs/cliui@8.0.2": - resolution: - { - integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==, - } - engines: { node: ">=12" } + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} - "@jridgewell/sourcemap-codec@1.5.5": - resolution: - { - integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==, - } + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} - "@rolldown/pluginutils@1.0.0-rc.2": - resolution: - { - integrity: sha512-izyXV/v+cHiRfozX62W9htOAvwMo4/bXKDrQ+vom1L1qRuexPock/7VZDAhnpHCLNejd3NJ6hiab+tO0D44Rgw==, - } + '@rolldown/pluginutils@1.0.0-rc.2': + resolution: {integrity: sha512-izyXV/v+cHiRfozX62W9htOAvwMo4/bXKDrQ+vom1L1qRuexPock/7VZDAhnpHCLNejd3NJ6hiab+tO0D44Rgw==} - "@rollup/rollup-android-arm-eabi@4.59.0": - resolution: - { - integrity: sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==, - } + '@rollup/rollup-android-arm-eabi@4.59.0': + resolution: {integrity: sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==} cpu: [arm] os: [android] - "@rollup/rollup-android-arm64@4.59.0": - resolution: - { - integrity: sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==, - } + '@rollup/rollup-android-arm64@4.59.0': + resolution: {integrity: sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==} cpu: [arm64] os: [android] - "@rollup/rollup-darwin-arm64@4.59.0": - resolution: - { - integrity: sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==, - } + '@rollup/rollup-darwin-arm64@4.59.0': + resolution: {integrity: sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==} cpu: [arm64] os: [darwin] - "@rollup/rollup-darwin-x64@4.59.0": - resolution: - { - integrity: sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==, - } + '@rollup/rollup-darwin-x64@4.59.0': + resolution: {integrity: sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==} cpu: [x64] os: [darwin] - "@rollup/rollup-freebsd-arm64@4.59.0": - resolution: - { - integrity: sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==, - } + '@rollup/rollup-freebsd-arm64@4.59.0': + resolution: {integrity: sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==} cpu: [arm64] os: [freebsd] - "@rollup/rollup-freebsd-x64@4.59.0": - resolution: - { - integrity: sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==, - } + '@rollup/rollup-freebsd-x64@4.59.0': + resolution: {integrity: sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==} cpu: [x64] os: [freebsd] - "@rollup/rollup-linux-arm-gnueabihf@4.59.0": - resolution: - { - integrity: sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==, - } + '@rollup/rollup-linux-arm-gnueabihf@4.59.0': + resolution: {integrity: sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==} cpu: [arm] os: [linux] libc: [glibc] - "@rollup/rollup-linux-arm-musleabihf@4.59.0": - resolution: - { - integrity: sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==, - } + '@rollup/rollup-linux-arm-musleabihf@4.59.0': + resolution: {integrity: sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==} cpu: [arm] os: [linux] libc: [musl] - "@rollup/rollup-linux-arm64-gnu@4.59.0": - resolution: - { - integrity: sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==, - } + '@rollup/rollup-linux-arm64-gnu@4.59.0': + resolution: {integrity: sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==} cpu: [arm64] os: [linux] libc: [glibc] - "@rollup/rollup-linux-arm64-musl@4.59.0": - resolution: - { - integrity: sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==, - } + '@rollup/rollup-linux-arm64-musl@4.59.0': + resolution: {integrity: sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==} cpu: [arm64] os: [linux] libc: [musl] - "@rollup/rollup-linux-loong64-gnu@4.59.0": - resolution: - { - integrity: sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==, - } + '@rollup/rollup-linux-loong64-gnu@4.59.0': + resolution: {integrity: sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==} cpu: [loong64] os: [linux] libc: [glibc] - "@rollup/rollup-linux-loong64-musl@4.59.0": - resolution: - { - integrity: sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==, - } + '@rollup/rollup-linux-loong64-musl@4.59.0': + resolution: {integrity: sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==} cpu: [loong64] os: [linux] libc: [musl] - "@rollup/rollup-linux-ppc64-gnu@4.59.0": - resolution: - { - integrity: sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==, - } + '@rollup/rollup-linux-ppc64-gnu@4.59.0': + resolution: {integrity: sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==} cpu: [ppc64] os: [linux] libc: [glibc] - "@rollup/rollup-linux-ppc64-musl@4.59.0": - resolution: - { - integrity: sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==, - } + '@rollup/rollup-linux-ppc64-musl@4.59.0': + resolution: {integrity: sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==} cpu: [ppc64] os: [linux] libc: [musl] - "@rollup/rollup-linux-riscv64-gnu@4.59.0": - resolution: - { - integrity: sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==, - } + '@rollup/rollup-linux-riscv64-gnu@4.59.0': + resolution: {integrity: sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==} cpu: [riscv64] os: [linux] libc: [glibc] - "@rollup/rollup-linux-riscv64-musl@4.59.0": - resolution: - { - integrity: sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==, - } + '@rollup/rollup-linux-riscv64-musl@4.59.0': + resolution: {integrity: sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==} cpu: [riscv64] os: [linux] libc: [musl] - "@rollup/rollup-linux-s390x-gnu@4.59.0": - resolution: - { - integrity: sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==, - } + '@rollup/rollup-linux-s390x-gnu@4.59.0': + resolution: {integrity: sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==} cpu: [s390x] os: [linux] libc: [glibc] - "@rollup/rollup-linux-x64-gnu@4.59.0": - resolution: - { - integrity: sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==, - } + '@rollup/rollup-linux-x64-gnu@4.59.0': + resolution: {integrity: sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==} cpu: [x64] os: [linux] libc: [glibc] - "@rollup/rollup-linux-x64-musl@4.59.0": - resolution: - { - integrity: sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==, - } + '@rollup/rollup-linux-x64-musl@4.59.0': + resolution: {integrity: sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==} cpu: [x64] os: [linux] libc: [musl] - "@rollup/rollup-openbsd-x64@4.59.0": - resolution: - { - integrity: sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==, - } + '@rollup/rollup-openbsd-x64@4.59.0': + resolution: {integrity: sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==} cpu: [x64] os: [openbsd] - "@rollup/rollup-openharmony-arm64@4.59.0": - resolution: - { - integrity: sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==, - } + '@rollup/rollup-openharmony-arm64@4.59.0': + resolution: {integrity: sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==} cpu: [arm64] os: [openharmony] - "@rollup/rollup-win32-arm64-msvc@4.59.0": - resolution: - { - integrity: sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==, - } + '@rollup/rollup-win32-arm64-msvc@4.59.0': + resolution: {integrity: sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==} cpu: [arm64] os: [win32] - "@rollup/rollup-win32-ia32-msvc@4.59.0": - resolution: - { - integrity: sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==, - } + '@rollup/rollup-win32-ia32-msvc@4.59.0': + resolution: {integrity: sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==} cpu: [ia32] os: [win32] - "@rollup/rollup-win32-x64-gnu@4.59.0": - resolution: - { - integrity: sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==, - } + '@rollup/rollup-win32-x64-gnu@4.59.0': + resolution: {integrity: sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==} cpu: [x64] os: [win32] - "@rollup/rollup-win32-x64-msvc@4.59.0": - resolution: - { - integrity: sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==, - } + '@rollup/rollup-win32-x64-msvc@4.59.0': + resolution: {integrity: sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==} cpu: [x64] os: [win32] - "@shikijs/core@3.23.0": - resolution: - { - integrity: sha512-NSWQz0riNb67xthdm5br6lAkvpDJRTgB36fxlo37ZzM2yq0PQFFzbd8psqC2XMPgCzo1fW6cVi18+ArJ44wqgA==, - } + '@shikijs/core@3.23.0': + resolution: {integrity: sha512-NSWQz0riNb67xthdm5br6lAkvpDJRTgB36fxlo37ZzM2yq0PQFFzbd8psqC2XMPgCzo1fW6cVi18+ArJ44wqgA==} - "@shikijs/engine-javascript@3.23.0": - resolution: - { - integrity: sha512-aHt9eiGFobmWR5uqJUViySI1bHMqrAgamWE1TYSUoftkAeCCAiGawPMwM+VCadylQtF4V3VNOZ5LmfItH5f3yA==, - } + '@shikijs/engine-javascript@3.23.0': + resolution: {integrity: sha512-aHt9eiGFobmWR5uqJUViySI1bHMqrAgamWE1TYSUoftkAeCCAiGawPMwM+VCadylQtF4V3VNOZ5LmfItH5f3yA==} - "@shikijs/engine-oniguruma@3.23.0": - resolution: - { - integrity: sha512-1nWINwKXxKKLqPibT5f4pAFLej9oZzQTsby8942OTlsJzOBZ0MWKiwzMsd+jhzu8YPCHAswGnnN1YtQfirL35g==, - } + '@shikijs/engine-oniguruma@3.23.0': + resolution: {integrity: sha512-1nWINwKXxKKLqPibT5f4pAFLej9oZzQTsby8942OTlsJzOBZ0MWKiwzMsd+jhzu8YPCHAswGnnN1YtQfirL35g==} - "@shikijs/langs@3.23.0": - resolution: - { - integrity: sha512-2Ep4W3Re5aB1/62RSYQInK9mM3HsLeB91cHqznAJMuylqjzNVAVCMnNWRHFtcNHXsoNRayP9z1qj4Sq3nMqYXg==, - } + '@shikijs/langs@3.23.0': + resolution: {integrity: sha512-2Ep4W3Re5aB1/62RSYQInK9mM3HsLeB91cHqznAJMuylqjzNVAVCMnNWRHFtcNHXsoNRayP9z1qj4Sq3nMqYXg==} - "@shikijs/themes@3.23.0": - resolution: - { - integrity: sha512-5qySYa1ZgAT18HR/ypENL9cUSGOeI2x+4IvYJu4JgVJdizn6kG4ia5Q1jDEOi7gTbN4RbuYtmHh0W3eccOrjMA==, - } + '@shikijs/themes@3.23.0': + resolution: {integrity: sha512-5qySYa1ZgAT18HR/ypENL9cUSGOeI2x+4IvYJu4JgVJdizn6kG4ia5Q1jDEOi7gTbN4RbuYtmHh0W3eccOrjMA==} - "@shikijs/transformers@3.23.0": - resolution: - { - integrity: sha512-F9msZVxdF+krQNSdQ4V+Ja5QemeAoTQ2jxt7nJCwhDsdF1JWS3KxIQXA3lQbyKwS3J61oHRUSv4jYWv3CkaKTQ==, - } + '@shikijs/transformers@3.23.0': + resolution: {integrity: sha512-F9msZVxdF+krQNSdQ4V+Ja5QemeAoTQ2jxt7nJCwhDsdF1JWS3KxIQXA3lQbyKwS3J61oHRUSv4jYWv3CkaKTQ==} - "@shikijs/types@3.23.0": - resolution: - { - integrity: sha512-3JZ5HXOZfYjsYSk0yPwBrkupyYSLpAE26Qc0HLghhZNGTZg/SKxXIIgoxOpmmeQP0RRSDJTk1/vPfw9tbw+jSQ==, - } + '@shikijs/types@3.23.0': + resolution: {integrity: sha512-3JZ5HXOZfYjsYSk0yPwBrkupyYSLpAE26Qc0HLghhZNGTZg/SKxXIIgoxOpmmeQP0RRSDJTk1/vPfw9tbw+jSQ==} - "@shikijs/vscode-textmate@10.0.2": - resolution: - { - integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==, - } + '@shikijs/vscode-textmate@10.0.2': + resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} - "@types/estree@1.0.8": - resolution: - { - integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==, - } + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} - "@types/hast@3.0.4": - resolution: - { - integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==, - } + '@types/hast@3.0.4': + resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} - "@types/linkify-it@5.0.0": - resolution: - { - integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==, - } + '@types/linkify-it@5.0.0': + resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==} - "@types/markdown-it@14.1.2": - resolution: - { - integrity: sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==, - } + '@types/markdown-it@14.1.2': + resolution: {integrity: sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==} - "@types/mdast@4.0.4": - resolution: - { - integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==, - } + '@types/mdast@4.0.4': + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} - "@types/mdurl@2.0.0": - resolution: - { - integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==, - } + '@types/mdurl@2.0.0': + resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==} - "@types/unist@3.0.3": - resolution: - { - integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==, - } + '@types/unist@3.0.3': + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} - "@types/web-bluetooth@0.0.21": - resolution: - { - integrity: sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==, - } + '@types/web-bluetooth@0.0.21': + resolution: {integrity: sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==} - "@ungap/structured-clone@1.3.0": - resolution: - { - integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==, - } + '@ungap/structured-clone@1.3.0': + resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} - "@vitejs/plugin-vue@6.0.5": - resolution: - { - integrity: sha512-bL3AxKuQySfk1iGcBsQnoRVexTPJq0Z/ixFVM8OhVJAP6ZXXXLtM7NFKWhLl30Kg7uTBqIaPXbh+nuQCuBDedg==, - } - engines: { node: ^20.19.0 || >=22.12.0 } + '@vitejs/plugin-vue@6.0.5': + resolution: {integrity: sha512-bL3AxKuQySfk1iGcBsQnoRVexTPJq0Z/ixFVM8OhVJAP6ZXXXLtM7NFKWhLl30Kg7uTBqIaPXbh+nuQCuBDedg==} + engines: {node: ^20.19.0 || >=22.12.0} peerDependencies: vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 vue: ^3.2.25 - "@vue/compiler-core@3.5.30": - resolution: - { - integrity: sha512-s3DfdZkcu/qExZ+td75015ljzHc6vE+30cFMGRPROYjqkroYI5NV2X1yAMX9UeyBNWB9MxCfPcsjpLS11nzkkw==, - } + '@vue/compiler-core@3.5.30': + resolution: {integrity: sha512-s3DfdZkcu/qExZ+td75015ljzHc6vE+30cFMGRPROYjqkroYI5NV2X1yAMX9UeyBNWB9MxCfPcsjpLS11nzkkw==} - "@vue/compiler-dom@3.5.30": - resolution: - { - integrity: sha512-eCFYESUEVYHhiMuK4SQTldO3RYxyMR/UQL4KdGD1Yrkfdx4m/HYuZ9jSfPdA+nWJY34VWndiYdW/wZXyiPEB9g==, - } + '@vue/compiler-dom@3.5.30': + resolution: {integrity: sha512-eCFYESUEVYHhiMuK4SQTldO3RYxyMR/UQL4KdGD1Yrkfdx4m/HYuZ9jSfPdA+nWJY34VWndiYdW/wZXyiPEB9g==} - "@vue/compiler-sfc@3.5.30": - resolution: - { - integrity: sha512-LqmFPDn89dtU9vI3wHJnwaV6GfTRD87AjWpTWpyrdVOObVtjIuSeZr181z5C4PmVx/V3j2p+0f7edFKGRMpQ5A==, - } + '@vue/compiler-sfc@3.5.30': + resolution: {integrity: sha512-LqmFPDn89dtU9vI3wHJnwaV6GfTRD87AjWpTWpyrdVOObVtjIuSeZr181z5C4PmVx/V3j2p+0f7edFKGRMpQ5A==} - "@vue/compiler-ssr@3.5.30": - resolution: - { - integrity: sha512-NsYK6OMTnx109PSL2IAyf62JP6EUdk4Dmj6AkWcJGBvN0dQoMYtVekAmdqgTtWQgEJo+Okstbf/1p7qZr5H+bA==, - } + '@vue/compiler-ssr@3.5.30': + resolution: {integrity: sha512-NsYK6OMTnx109PSL2IAyf62JP6EUdk4Dmj6AkWcJGBvN0dQoMYtVekAmdqgTtWQgEJo+Okstbf/1p7qZr5H+bA==} - "@vue/devtools-api@8.1.0": - resolution: - { - integrity: sha512-O44X57jjkLKbLEc4OgL/6fEPOOanRJU8kYpCE8qfKlV96RQZcdzrcLI5mxMuVRUeXhHKIHGhCpHacyCk0HyO4w==, - } + '@vue/devtools-api@8.1.0': + resolution: {integrity: sha512-O44X57jjkLKbLEc4OgL/6fEPOOanRJU8kYpCE8qfKlV96RQZcdzrcLI5mxMuVRUeXhHKIHGhCpHacyCk0HyO4w==} - "@vue/devtools-kit@8.1.0": - resolution: - { - integrity: sha512-/NZlS4WtGIB54DA/z10gzk+n/V7zaqSzYZOVlg2CfdnpIKdB61bd7JDIMxf/zrtX41zod8E2/bbEBoW/d7x70Q==, - } + '@vue/devtools-kit@8.1.0': + resolution: {integrity: sha512-/NZlS4WtGIB54DA/z10gzk+n/V7zaqSzYZOVlg2CfdnpIKdB61bd7JDIMxf/zrtX41zod8E2/bbEBoW/d7x70Q==} - "@vue/devtools-shared@8.1.0": - resolution: - { - integrity: sha512-h8uCb4Qs8UT8VdTT5yjY6tOJ//qH7EpxToixR0xqejR55t5OdISIg7AJ7eBkhBs8iu1qG5gY3QQNN1DF1EelAA==, - } + '@vue/devtools-shared@8.1.0': + resolution: {integrity: sha512-h8uCb4Qs8UT8VdTT5yjY6tOJ//qH7EpxToixR0xqejR55t5OdISIg7AJ7eBkhBs8iu1qG5gY3QQNN1DF1EelAA==} - "@vue/reactivity@3.5.30": - resolution: - { - integrity: sha512-179YNgKATuwj9gB+66snskRDOitDiuOZqkYia7mHKJaidOMo/WJxHKF8DuGc4V4XbYTJANlfEKb0yxTQotnx4Q==, - } + '@vue/reactivity@3.5.30': + resolution: {integrity: sha512-179YNgKATuwj9gB+66snskRDOitDiuOZqkYia7mHKJaidOMo/WJxHKF8DuGc4V4XbYTJANlfEKb0yxTQotnx4Q==} - "@vue/runtime-core@3.5.30": - resolution: - { - integrity: sha512-e0Z+8PQsUTdwV8TtEsLzUM7SzC7lQwYKePydb7K2ZnmS6jjND+WJXkmmfh/swYzRyfP1EY3fpdesyYoymCzYfg==, - } + '@vue/runtime-core@3.5.30': + resolution: {integrity: sha512-e0Z+8PQsUTdwV8TtEsLzUM7SzC7lQwYKePydb7K2ZnmS6jjND+WJXkmmfh/swYzRyfP1EY3fpdesyYoymCzYfg==} - "@vue/runtime-dom@3.5.30": - resolution: - { - integrity: sha512-2UIGakjU4WSQ0T4iwDEW0W7vQj6n7AFn7taqZ9Cvm0Q/RA2FFOziLESrDL4GmtI1wV3jXg5nMoJSYO66egDUBw==, - } + '@vue/runtime-dom@3.5.30': + resolution: {integrity: sha512-2UIGakjU4WSQ0T4iwDEW0W7vQj6n7AFn7taqZ9Cvm0Q/RA2FFOziLESrDL4GmtI1wV3jXg5nMoJSYO66egDUBw==} - "@vue/server-renderer@3.5.30": - resolution: - { - integrity: sha512-v+R34icapydRwbZRD0sXwtHqrQJv38JuMB4JxbOxd8NEpGLny7cncMp53W9UH/zo4j8eDHjQ1dEJXwzFQknjtQ==, - } + '@vue/server-renderer@3.5.30': + resolution: {integrity: sha512-v+R34icapydRwbZRD0sXwtHqrQJv38JuMB4JxbOxd8NEpGLny7cncMp53W9UH/zo4j8eDHjQ1dEJXwzFQknjtQ==} peerDependencies: vue: 3.5.30 - "@vue/shared@3.5.30": - resolution: - { - integrity: sha512-YXgQ7JjaO18NeK2K9VTbDHaFy62WrObMa6XERNfNOkAhD1F1oDSf3ZJ7K6GqabZ0BvSDHajp8qfS5Sa2I9n8uQ==, - } + '@vue/shared@3.5.30': + resolution: {integrity: sha512-YXgQ7JjaO18NeK2K9VTbDHaFy62WrObMa6XERNfNOkAhD1F1oDSf3ZJ7K6GqabZ0BvSDHajp8qfS5Sa2I9n8uQ==} - "@vueuse/core@14.2.1": - resolution: - { - integrity: sha512-3vwDzV+GDUNpdegRY6kzpLm4Igptq+GA0QkJ3W61Iv27YWwW/ufSlOfgQIpN6FZRMG0mkaz4gglJRtq5SeJyIQ==, - } + '@vueuse/core@14.2.1': + resolution: {integrity: sha512-3vwDzV+GDUNpdegRY6kzpLm4Igptq+GA0QkJ3W61Iv27YWwW/ufSlOfgQIpN6FZRMG0mkaz4gglJRtq5SeJyIQ==} peerDependencies: vue: ^3.5.0 - "@vueuse/integrations@14.2.1": - resolution: - { - integrity: sha512-2LIUpBi/67PoXJGqSDQUF0pgQWpNHh7beiA+KG2AbybcNm+pTGWT6oPGlBgUoDWmYwfeQqM/uzOHqcILpKL7nA==, - } + '@vueuse/integrations@14.2.1': + resolution: {integrity: sha512-2LIUpBi/67PoXJGqSDQUF0pgQWpNHh7beiA+KG2AbybcNm+pTGWT6oPGlBgUoDWmYwfeQqM/uzOHqcILpKL7nA==} peerDependencies: async-validator: ^4 axios: ^1 @@ -793,183 +504,102 @@ packages: universal-cookie: optional: true - "@vueuse/metadata@14.2.1": - resolution: - { - integrity: sha512-1ButlVtj5Sb/HDtIy1HFr1VqCP4G6Ypqt5MAo0lCgjokrk2mvQKsK2uuy0vqu/Ks+sHfuHo0B9Y9jn9xKdjZsw==, - } + '@vueuse/metadata@14.2.1': + resolution: {integrity: sha512-1ButlVtj5Sb/HDtIy1HFr1VqCP4G6Ypqt5MAo0lCgjokrk2mvQKsK2uuy0vqu/Ks+sHfuHo0B9Y9jn9xKdjZsw==} - "@vueuse/shared@14.2.1": - resolution: - { - integrity: sha512-shTJncjV9JTI4oVNyF1FQonetYAiTBd+Qj7cY89SWbXSkx7gyhrgtEdF2ZAVWS1S3SHlaROO6F2IesJxQEkZBw==, - } + '@vueuse/shared@14.2.1': + resolution: {integrity: sha512-shTJncjV9JTI4oVNyF1FQonetYAiTBd+Qj7cY89SWbXSkx7gyhrgtEdF2ZAVWS1S3SHlaROO6F2IesJxQEkZBw==} peerDependencies: vue: ^3.5.0 ansi-regex@5.0.1: - resolution: - { - integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} ansi-regex@6.2.2: - resolution: - { - integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==, - } - engines: { node: ">=12" } + resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} + engines: {node: '>=12'} ansi-styles@4.3.0: - resolution: - { - integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} ansi-styles@6.2.3: - resolution: - { - integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==, - } - engines: { node: ">=12" } + resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} + engines: {node: '>=12'} argparse@1.0.10: - resolution: - { - integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==, - } + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} birpc@2.9.0: - resolution: - { - integrity: sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw==, - } + resolution: {integrity: sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw==} ccount@2.0.1: - resolution: - { - integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==, - } + resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} character-entities-html4@2.1.0: - resolution: - { - integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==, - } + resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} character-entities-legacy@3.0.0: - resolution: - { - integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==, - } + resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} color-convert@2.0.1: - resolution: - { - integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==, - } - engines: { node: ">=7.0.0" } + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} color-name@1.1.4: - resolution: - { - integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==, - } + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} comma-separated-tokens@2.0.3: - resolution: - { - integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==, - } + resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} cross-spawn@7.0.6: - resolution: - { - integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==, - } - engines: { node: ">= 8" } + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} csstype@3.2.3: - resolution: - { - integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==, - } + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} dequal@2.0.3: - resolution: - { - integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==, - } - engines: { node: ">=6" } + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} devlop@1.1.0: - resolution: - { - integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==, - } + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} eastasianwidth@0.2.0: - resolution: - { - integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==, - } + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} emoji-regex@8.0.0: - resolution: - { - integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==, - } + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} emoji-regex@9.2.2: - resolution: - { - integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==, - } + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} entities@7.0.1: - resolution: - { - integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==, - } - engines: { node: ">=0.12" } + resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==} + engines: {node: '>=0.12'} esbuild@0.27.4: - resolution: - { - integrity: sha512-Rq4vbHnYkK5fws5NF7MYTU68FPRE1ajX7heQ/8QXXWqNgqqJ/GkmmyxIzUnf2Sr/bakf8l54716CcMGHYhMrrQ==, - } - engines: { node: ">=18" } + resolution: {integrity: sha512-Rq4vbHnYkK5fws5NF7MYTU68FPRE1ajX7heQ/8QXXWqNgqqJ/GkmmyxIzUnf2Sr/bakf8l54716CcMGHYhMrrQ==} + engines: {node: '>=18'} hasBin: true esprima@4.0.1: - resolution: - { - integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==, - } - engines: { node: ">=4" } + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} hasBin: true estree-walker@2.0.2: - resolution: - { - integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==, - } + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} extend-shallow@2.0.1: - resolution: - { - integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==, - } - engines: { node: ">=0.10.0" } + resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} + engines: {node: '>=0.10.0'} fdir@6.5.0: - resolution: - { - integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==, - } - engines: { node: ">=12.0.0" } + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} peerDependencies: picomatch: ^3 || ^4 peerDependenciesMeta: @@ -977,463 +607,259 @@ packages: optional: true focus-trap@7.8.0: - resolution: - { - integrity: sha512-/yNdlIkpWbM0ptxno3ONTuf+2g318kh2ez3KSeZN5dZ8YC6AAmgeWz+GasYYiBJPFaYcSAPeu4GfhUaChzIJXA==, - } + resolution: {integrity: sha512-/yNdlIkpWbM0ptxno3ONTuf+2g318kh2ez3KSeZN5dZ8YC6AAmgeWz+GasYYiBJPFaYcSAPeu4GfhUaChzIJXA==} foreground-child@3.3.1: - resolution: - { - integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==, - } - engines: { node: ">=14" } + resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} + engines: {node: '>=14'} fsevents@2.3.3: - resolution: - { - integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==, - } - engines: { node: ^8.16.0 || ^10.6.0 || >=11.0.0 } + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] glob@11.1.0: - resolution: - { - integrity: sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==, - } - engines: { node: 20 || >=22 } + resolution: {integrity: sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==} + engines: {node: 20 || >=22} deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me hasBin: true gray-matter@4.0.3: - resolution: - { - integrity: sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==, - } - engines: { node: ">=6.0" } + resolution: {integrity: sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==} + engines: {node: '>=6.0'} hast-util-to-html@9.0.5: - resolution: - { - integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==, - } + resolution: {integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==} hast-util-whitespace@3.0.0: - resolution: - { - integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==, - } + resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} hookable@5.5.3: - resolution: - { - integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==, - } + resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==} html-void-elements@3.0.0: - resolution: - { - integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==, - } + resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} is-extendable@0.1.1: - resolution: - { - integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==, - } - engines: { node: ">=0.10.0" } + resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} + engines: {node: '>=0.10.0'} is-fullwidth-code-point@3.0.0: - resolution: - { - integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} isexe@2.0.0: - resolution: - { - integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==, - } + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} jackspeak@4.1.1: - resolution: - { - integrity: sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==, - } - engines: { node: 20 || >=22 } + resolution: {integrity: sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==} + engines: {node: 20 || >=22} js-yaml@3.14.2: - resolution: - { - integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==, - } + resolution: {integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==} hasBin: true kind-of@6.0.3: - resolution: - { - integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==, - } - engines: { node: ">=0.10.0" } + resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} + engines: {node: '>=0.10.0'} lru-cache@11.2.4: - resolution: - { - integrity: sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==, - } - engines: { node: 20 || >=22 } + resolution: {integrity: sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==} + engines: {node: 20 || >=22} magic-string@0.30.21: - resolution: - { - integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==, - } + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} mark.js@8.11.1: - resolution: - { - integrity: sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==, - } + resolution: {integrity: sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==} mdast-util-to-hast@13.2.1: - resolution: - { - integrity: sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==, - } + resolution: {integrity: sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==} micromark-util-character@2.1.1: - resolution: - { - integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==, - } + resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} micromark-util-encode@2.0.1: - resolution: - { - integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==, - } + resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} micromark-util-sanitize-uri@2.0.1: - resolution: - { - integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==, - } + resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} micromark-util-symbol@2.0.1: - resolution: - { - integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==, - } + resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} micromark-util-types@2.0.2: - resolution: - { - integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==, - } + resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} minimatch@10.1.1: - resolution: - { - integrity: sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==, - } - engines: { node: 20 || >=22 } + resolution: {integrity: sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==} + engines: {node: 20 || >=22} minipass@7.1.2: - resolution: - { - integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==, - } - engines: { node: ">=16 || 14 >=14.17" } + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} minisearch@7.2.0: - resolution: - { - integrity: sha512-dqT2XBYUOZOiC5t2HRnwADjhNS2cecp9u+TJRiJ1Qp/f5qjkeT5APcGPjHw+bz89Ms8Jp+cG4AlE+QZ/QnDglg==, - } + resolution: {integrity: sha512-dqT2XBYUOZOiC5t2HRnwADjhNS2cecp9u+TJRiJ1Qp/f5qjkeT5APcGPjHw+bz89Ms8Jp+cG4AlE+QZ/QnDglg==} nanoid@3.3.11: - resolution: - { - integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==, - } - engines: { node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1 } + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true oniguruma-parser@0.12.1: - resolution: - { - integrity: sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w==, - } + resolution: {integrity: sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w==} oniguruma-to-es@4.3.5: - resolution: - { - integrity: sha512-Zjygswjpsewa0NLTsiizVuMQZbp0MDyM6lIt66OxsF21npUDlzpHi1Mgb/qhQdkb+dWFTzJmFbEWdvZgRho8eQ==, - } + resolution: {integrity: sha512-Zjygswjpsewa0NLTsiizVuMQZbp0MDyM6lIt66OxsF21npUDlzpHi1Mgb/qhQdkb+dWFTzJmFbEWdvZgRho8eQ==} package-json-from-dist@1.0.1: - resolution: - { - integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==, - } + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} path-key@3.1.1: - resolution: - { - integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} path-scurry@2.0.1: - resolution: - { - integrity: sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==, - } - engines: { node: 20 || >=22 } + resolution: {integrity: sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==} + engines: {node: 20 || >=22} perfect-debounce@2.1.0: - resolution: - { - integrity: sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g==, - } + resolution: {integrity: sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g==} picocolors@1.1.1: - resolution: - { - integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==, - } + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} picomatch@4.0.3: - resolution: - { - integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==, - } - engines: { node: ">=12" } + resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} + engines: {node: '>=12'} postcss@8.5.8: - resolution: - { - integrity: sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==, - } - engines: { node: ^10 || ^12 || >=14 } + resolution: {integrity: sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==} + engines: {node: ^10 || ^12 || >=14} property-information@7.1.0: - resolution: - { - integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==, - } + resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==} qsu@1.10.4: - resolution: - { - integrity: sha512-v5RhwvHMkDdbXEaAxQh5re8q7DiG6EE70+CNwYVA6wZsa4gUrpur+D8lIO3PrzeCj3azc/S79X5v3BH8ILfr9A==, - } - engines: { node: ">=18.0.0" } + resolution: {integrity: sha512-v5RhwvHMkDdbXEaAxQh5re8q7DiG6EE70+CNwYVA6wZsa4gUrpur+D8lIO3PrzeCj3azc/S79X5v3BH8ILfr9A==} + engines: {node: '>=18.0.0'} regex-recursion@6.0.2: - resolution: - { - integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==, - } + resolution: {integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==} regex-utilities@2.3.0: - resolution: - { - integrity: sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==, - } + resolution: {integrity: sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==} regex@6.1.0: - resolution: - { - integrity: sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==, - } + resolution: {integrity: sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==} rollup@4.59.0: - resolution: - { - integrity: sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==, - } - engines: { node: ">=18.0.0", npm: ">=8.0.0" } + resolution: {integrity: sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true section-matter@1.0.0: - resolution: - { - integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==, - } - engines: { node: ">=4" } + resolution: {integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==} + engines: {node: '>=4'} shebang-command@2.0.0: - resolution: - { - integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} shebang-regex@3.0.0: - resolution: - { - integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} shiki@3.23.0: - resolution: - { - integrity: sha512-55Dj73uq9ZXL5zyeRPzHQsK7Nbyt6Y10k5s7OjuFZGMhpp4r/rsLBH0o/0fstIzX1Lep9VxefWljK/SKCzygIA==, - } + resolution: {integrity: sha512-55Dj73uq9ZXL5zyeRPzHQsK7Nbyt6Y10k5s7OjuFZGMhpp4r/rsLBH0o/0fstIzX1Lep9VxefWljK/SKCzygIA==} signal-exit@4.1.0: - resolution: - { - integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==, - } - engines: { node: ">=14" } + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} source-map-js@1.2.1: - resolution: - { - integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==, - } - engines: { node: ">=0.10.0" } + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} space-separated-tokens@2.0.2: - resolution: - { - integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==, - } + resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} sprintf-js@1.0.3: - resolution: - { - integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==, - } + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} string-width@4.2.3: - resolution: - { - integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} string-width@5.1.2: - resolution: - { - integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==, - } - engines: { node: ">=12" } + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} stringify-entities@4.0.4: - resolution: - { - integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==, - } + resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} strip-ansi@6.0.1: - resolution: - { - integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} strip-ansi@7.1.2: - resolution: - { - integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==, - } - engines: { node: ">=12" } + resolution: {integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==} + engines: {node: '>=12'} strip-bom-string@1.0.0: - resolution: - { - integrity: sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==, - } - engines: { node: ">=0.10.0" } + resolution: {integrity: sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==} + engines: {node: '>=0.10.0'} tabbable@6.4.0: - resolution: - { - integrity: sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg==, - } + resolution: {integrity: sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg==} tinyglobby@0.2.15: - resolution: - { - integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==, - } - engines: { node: ">=12.0.0" } + resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} + engines: {node: '>=12.0.0'} trim-lines@3.0.1: - resolution: - { - integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==, - } + resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} unist-util-is@6.0.1: - resolution: - { - integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==, - } + resolution: {integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==} unist-util-position@5.0.0: - resolution: - { - integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==, - } + resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} unist-util-stringify-position@4.0.0: - resolution: - { - integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==, - } + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} unist-util-visit-parents@6.0.2: - resolution: - { - integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==, - } + resolution: {integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==} unist-util-visit@5.1.0: - resolution: - { - integrity: sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==, - } + resolution: {integrity: sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==} vfile-message@4.0.3: - resolution: - { - integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==, - } + resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} vfile@6.0.3: - resolution: - { - integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==, - } + resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} vite@7.3.1: - resolution: - { - integrity: sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==, - } - engines: { node: ^20.19.0 || >=22.12.0 } + resolution: {integrity: sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==} + engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: - "@types/node": ^20.19.0 || >=22.12.0 - jiti: ">=1.21.0" + '@types/node': ^20.19.0 || >=22.12.0 + jiti: '>=1.21.0' less: ^4.0.0 lightningcss: ^1.21.0 sass: ^1.70.0 sass-embedded: ^1.70.0 - stylus: ">=0.54.8" + stylus: '>=0.54.8' sugarss: ^5.0.0 terser: ^5.16.0 tsx: ^4.8.1 yaml: ^2.4.2 peerDependenciesMeta: - "@types/node": + '@types/node': optional: true jiti: optional: true @@ -1457,21 +883,15 @@ packages: optional: true vitepress-sidebar@1.33.1: - resolution: - { - integrity: sha512-wPUbXezGakVldawixeRW5tKQTLKoMj2t4nWoThKfCltBM/9a38IE+wCXmmRNW22ZKC32SD/X/sG6NyCTK8QBRg==, - } - engines: { node: ">=18.0.0" } + resolution: {integrity: sha512-wPUbXezGakVldawixeRW5tKQTLKoMj2t4nWoThKfCltBM/9a38IE+wCXmmRNW22ZKC32SD/X/sG6NyCTK8QBRg==} + engines: {node: '>=18.0.0'} vitepress@2.0.0-alpha.16: - resolution: - { - integrity: sha512-w1nwsefDVIsje7BZr2tsKxkZutDGjG0YoQ2yxO7+a9tvYVqfljYbwj5LMYkPy8Tb7YbPwa22HtIhk62jbrvuEQ==, - } + resolution: {integrity: sha512-w1nwsefDVIsje7BZr2tsKxkZutDGjG0YoQ2yxO7+a9tvYVqfljYbwj5LMYkPy8Tb7YbPwa22HtIhk62jbrvuEQ==} hasBin: true peerDependencies: markdown-it-mathjax3: ^4 - oxc-minify: "*" + oxc-minify: '*' postcss: ^8 peerDependenciesMeta: markdown-it-mathjax3: @@ -1482,155 +902,141 @@ packages: optional: true vue@3.5.30: - resolution: - { - integrity: sha512-hTHLc6VNZyzzEH/l7PFGjpcTvUgiaPK5mdLkbjrTeWSRcEfxFrv56g/XckIYlE9ckuobsdwqd5mk2g1sBkMewg==, - } + resolution: {integrity: sha512-hTHLc6VNZyzzEH/l7PFGjpcTvUgiaPK5mdLkbjrTeWSRcEfxFrv56g/XckIYlE9ckuobsdwqd5mk2g1sBkMewg==} peerDependencies: - typescript: "*" + typescript: '*' peerDependenciesMeta: typescript: optional: true which@2.0.2: - resolution: - { - integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==, - } - engines: { node: ">= 8" } + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} hasBin: true wrap-ansi@7.0.0: - resolution: - { - integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==, - } - engines: { node: ">=10" } + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} wrap-ansi@8.1.0: - resolution: - { - integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==, - } - engines: { node: ">=12" } + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} zwitch@2.0.4: - resolution: - { - integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==, - } + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} snapshots: - "@babel/helper-string-parser@7.27.1": {} - "@babel/helper-validator-identifier@7.28.5": {} + '@babel/helper-string-parser@7.27.1': {} - "@babel/parser@7.29.0": + '@babel/helper-validator-identifier@7.28.5': {} + + '@babel/parser@7.29.0': dependencies: - "@babel/types": 7.29.0 + '@babel/types': 7.29.0 - "@babel/types@7.29.0": + '@babel/types@7.29.0': dependencies: - "@babel/helper-string-parser": 7.27.1 - "@babel/helper-validator-identifier": 7.28.5 + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 - "@docsearch/css@4.6.0": {} + '@docsearch/css@4.6.0': {} - "@docsearch/js@4.6.0": {} + '@docsearch/js@4.6.0': {} - "@docsearch/sidepanel-js@4.6.0": {} + '@docsearch/sidepanel-js@4.6.0': {} - "@esbuild/aix-ppc64@0.27.4": + '@esbuild/aix-ppc64@0.27.4': optional: true - "@esbuild/android-arm64@0.27.4": + '@esbuild/android-arm64@0.27.4': optional: true - "@esbuild/android-arm@0.27.4": + '@esbuild/android-arm@0.27.4': optional: true - "@esbuild/android-x64@0.27.4": + '@esbuild/android-x64@0.27.4': optional: true - "@esbuild/darwin-arm64@0.27.4": + '@esbuild/darwin-arm64@0.27.4': optional: true - "@esbuild/darwin-x64@0.27.4": + '@esbuild/darwin-x64@0.27.4': optional: true - "@esbuild/freebsd-arm64@0.27.4": + '@esbuild/freebsd-arm64@0.27.4': optional: true - "@esbuild/freebsd-x64@0.27.4": + '@esbuild/freebsd-x64@0.27.4': optional: true - "@esbuild/linux-arm64@0.27.4": + '@esbuild/linux-arm64@0.27.4': optional: true - "@esbuild/linux-arm@0.27.4": + '@esbuild/linux-arm@0.27.4': optional: true - "@esbuild/linux-ia32@0.27.4": + '@esbuild/linux-ia32@0.27.4': optional: true - "@esbuild/linux-loong64@0.27.4": + '@esbuild/linux-loong64@0.27.4': optional: true - "@esbuild/linux-mips64el@0.27.4": + '@esbuild/linux-mips64el@0.27.4': optional: true - "@esbuild/linux-ppc64@0.27.4": + '@esbuild/linux-ppc64@0.27.4': optional: true - "@esbuild/linux-riscv64@0.27.4": + '@esbuild/linux-riscv64@0.27.4': optional: true - "@esbuild/linux-s390x@0.27.4": + '@esbuild/linux-s390x@0.27.4': optional: true - "@esbuild/linux-x64@0.27.4": + '@esbuild/linux-x64@0.27.4': optional: true - "@esbuild/netbsd-arm64@0.27.4": + '@esbuild/netbsd-arm64@0.27.4': optional: true - "@esbuild/netbsd-x64@0.27.4": + '@esbuild/netbsd-x64@0.27.4': optional: true - "@esbuild/openbsd-arm64@0.27.4": + '@esbuild/openbsd-arm64@0.27.4': optional: true - "@esbuild/openbsd-x64@0.27.4": + '@esbuild/openbsd-x64@0.27.4': optional: true - "@esbuild/openharmony-arm64@0.27.4": + '@esbuild/openharmony-arm64@0.27.4': optional: true - "@esbuild/sunos-x64@0.27.4": + '@esbuild/sunos-x64@0.27.4': optional: true - "@esbuild/win32-arm64@0.27.4": + '@esbuild/win32-arm64@0.27.4': optional: true - "@esbuild/win32-ia32@0.27.4": + '@esbuild/win32-ia32@0.27.4': optional: true - "@esbuild/win32-x64@0.27.4": + '@esbuild/win32-x64@0.27.4': optional: true - "@iconify-json/simple-icons@1.2.74": + '@iconify-json/simple-icons@1.2.74': dependencies: - "@iconify/types": 2.0.0 + '@iconify/types': 2.0.0 - "@iconify/types@2.0.0": {} + '@iconify/types@2.0.0': {} - "@isaacs/balanced-match@4.0.1": {} + '@isaacs/balanced-match@4.0.1': {} - "@isaacs/brace-expansion@5.0.0": + '@isaacs/brace-expansion@5.0.0': dependencies: - "@isaacs/balanced-match": 4.0.1 + '@isaacs/balanced-match': 4.0.1 - "@isaacs/cliui@8.0.2": + '@isaacs/cliui@8.0.2': dependencies: string-width: 5.1.2 string-width-cjs: string-width@4.2.3 @@ -1639,239 +1045,239 @@ snapshots: wrap-ansi: 8.1.0 wrap-ansi-cjs: wrap-ansi@7.0.0 - "@jridgewell/sourcemap-codec@1.5.5": {} + '@jridgewell/sourcemap-codec@1.5.5': {} - "@rolldown/pluginutils@1.0.0-rc.2": {} + '@rolldown/pluginutils@1.0.0-rc.2': {} - "@rollup/rollup-android-arm-eabi@4.59.0": + '@rollup/rollup-android-arm-eabi@4.59.0': optional: true - "@rollup/rollup-android-arm64@4.59.0": + '@rollup/rollup-android-arm64@4.59.0': optional: true - "@rollup/rollup-darwin-arm64@4.59.0": + '@rollup/rollup-darwin-arm64@4.59.0': optional: true - "@rollup/rollup-darwin-x64@4.59.0": + '@rollup/rollup-darwin-x64@4.59.0': optional: true - "@rollup/rollup-freebsd-arm64@4.59.0": + '@rollup/rollup-freebsd-arm64@4.59.0': optional: true - "@rollup/rollup-freebsd-x64@4.59.0": + '@rollup/rollup-freebsd-x64@4.59.0': optional: true - "@rollup/rollup-linux-arm-gnueabihf@4.59.0": + '@rollup/rollup-linux-arm-gnueabihf@4.59.0': optional: true - "@rollup/rollup-linux-arm-musleabihf@4.59.0": + '@rollup/rollup-linux-arm-musleabihf@4.59.0': optional: true - "@rollup/rollup-linux-arm64-gnu@4.59.0": + '@rollup/rollup-linux-arm64-gnu@4.59.0': optional: true - "@rollup/rollup-linux-arm64-musl@4.59.0": + '@rollup/rollup-linux-arm64-musl@4.59.0': optional: true - "@rollup/rollup-linux-loong64-gnu@4.59.0": + '@rollup/rollup-linux-loong64-gnu@4.59.0': optional: true - "@rollup/rollup-linux-loong64-musl@4.59.0": + '@rollup/rollup-linux-loong64-musl@4.59.0': optional: true - "@rollup/rollup-linux-ppc64-gnu@4.59.0": + '@rollup/rollup-linux-ppc64-gnu@4.59.0': optional: true - "@rollup/rollup-linux-ppc64-musl@4.59.0": + '@rollup/rollup-linux-ppc64-musl@4.59.0': optional: true - "@rollup/rollup-linux-riscv64-gnu@4.59.0": + '@rollup/rollup-linux-riscv64-gnu@4.59.0': optional: true - "@rollup/rollup-linux-riscv64-musl@4.59.0": + '@rollup/rollup-linux-riscv64-musl@4.59.0': optional: true - "@rollup/rollup-linux-s390x-gnu@4.59.0": + '@rollup/rollup-linux-s390x-gnu@4.59.0': optional: true - "@rollup/rollup-linux-x64-gnu@4.59.0": + '@rollup/rollup-linux-x64-gnu@4.59.0': optional: true - "@rollup/rollup-linux-x64-musl@4.59.0": + '@rollup/rollup-linux-x64-musl@4.59.0': optional: true - "@rollup/rollup-openbsd-x64@4.59.0": + '@rollup/rollup-openbsd-x64@4.59.0': optional: true - "@rollup/rollup-openharmony-arm64@4.59.0": + '@rollup/rollup-openharmony-arm64@4.59.0': optional: true - "@rollup/rollup-win32-arm64-msvc@4.59.0": + '@rollup/rollup-win32-arm64-msvc@4.59.0': optional: true - "@rollup/rollup-win32-ia32-msvc@4.59.0": + '@rollup/rollup-win32-ia32-msvc@4.59.0': optional: true - "@rollup/rollup-win32-x64-gnu@4.59.0": + '@rollup/rollup-win32-x64-gnu@4.59.0': optional: true - "@rollup/rollup-win32-x64-msvc@4.59.0": + '@rollup/rollup-win32-x64-msvc@4.59.0': optional: true - "@shikijs/core@3.23.0": + '@shikijs/core@3.23.0': dependencies: - "@shikijs/types": 3.23.0 - "@shikijs/vscode-textmate": 10.0.2 - "@types/hast": 3.0.4 + '@shikijs/types': 3.23.0 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 hast-util-to-html: 9.0.5 - "@shikijs/engine-javascript@3.23.0": + '@shikijs/engine-javascript@3.23.0': dependencies: - "@shikijs/types": 3.23.0 - "@shikijs/vscode-textmate": 10.0.2 + '@shikijs/types': 3.23.0 + '@shikijs/vscode-textmate': 10.0.2 oniguruma-to-es: 4.3.5 - "@shikijs/engine-oniguruma@3.23.0": + '@shikijs/engine-oniguruma@3.23.0': dependencies: - "@shikijs/types": 3.23.0 - "@shikijs/vscode-textmate": 10.0.2 + '@shikijs/types': 3.23.0 + '@shikijs/vscode-textmate': 10.0.2 - "@shikijs/langs@3.23.0": + '@shikijs/langs@3.23.0': dependencies: - "@shikijs/types": 3.23.0 + '@shikijs/types': 3.23.0 - "@shikijs/themes@3.23.0": + '@shikijs/themes@3.23.0': dependencies: - "@shikijs/types": 3.23.0 + '@shikijs/types': 3.23.0 - "@shikijs/transformers@3.23.0": + '@shikijs/transformers@3.23.0': dependencies: - "@shikijs/core": 3.23.0 - "@shikijs/types": 3.23.0 + '@shikijs/core': 3.23.0 + '@shikijs/types': 3.23.0 - "@shikijs/types@3.23.0": + '@shikijs/types@3.23.0': dependencies: - "@shikijs/vscode-textmate": 10.0.2 - "@types/hast": 3.0.4 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 - "@shikijs/vscode-textmate@10.0.2": {} + '@shikijs/vscode-textmate@10.0.2': {} - "@types/estree@1.0.8": {} + '@types/estree@1.0.8': {} - "@types/hast@3.0.4": + '@types/hast@3.0.4': dependencies: - "@types/unist": 3.0.3 + '@types/unist': 3.0.3 - "@types/linkify-it@5.0.0": {} + '@types/linkify-it@5.0.0': {} - "@types/markdown-it@14.1.2": + '@types/markdown-it@14.1.2': dependencies: - "@types/linkify-it": 5.0.0 - "@types/mdurl": 2.0.0 + '@types/linkify-it': 5.0.0 + '@types/mdurl': 2.0.0 - "@types/mdast@4.0.4": + '@types/mdast@4.0.4': dependencies: - "@types/unist": 3.0.3 + '@types/unist': 3.0.3 - "@types/mdurl@2.0.0": {} + '@types/mdurl@2.0.0': {} - "@types/unist@3.0.3": {} + '@types/unist@3.0.3': {} - "@types/web-bluetooth@0.0.21": {} + '@types/web-bluetooth@0.0.21': {} - "@ungap/structured-clone@1.3.0": {} + '@ungap/structured-clone@1.3.0': {} - "@vitejs/plugin-vue@6.0.5(vite@7.3.1)(vue@3.5.30)": + '@vitejs/plugin-vue@6.0.5(vite@7.3.1)(vue@3.5.30)': dependencies: - "@rolldown/pluginutils": 1.0.0-rc.2 + '@rolldown/pluginutils': 1.0.0-rc.2 vite: 7.3.1 vue: 3.5.30 - "@vue/compiler-core@3.5.30": + '@vue/compiler-core@3.5.30': dependencies: - "@babel/parser": 7.29.0 - "@vue/shared": 3.5.30 + '@babel/parser': 7.29.0 + '@vue/shared': 3.5.30 entities: 7.0.1 estree-walker: 2.0.2 source-map-js: 1.2.1 - "@vue/compiler-dom@3.5.30": + '@vue/compiler-dom@3.5.30': dependencies: - "@vue/compiler-core": 3.5.30 - "@vue/shared": 3.5.30 + '@vue/compiler-core': 3.5.30 + '@vue/shared': 3.5.30 - "@vue/compiler-sfc@3.5.30": + '@vue/compiler-sfc@3.5.30': dependencies: - "@babel/parser": 7.29.0 - "@vue/compiler-core": 3.5.30 - "@vue/compiler-dom": 3.5.30 - "@vue/compiler-ssr": 3.5.30 - "@vue/shared": 3.5.30 + '@babel/parser': 7.29.0 + '@vue/compiler-core': 3.5.30 + '@vue/compiler-dom': 3.5.30 + '@vue/compiler-ssr': 3.5.30 + '@vue/shared': 3.5.30 estree-walker: 2.0.2 magic-string: 0.30.21 postcss: 8.5.8 source-map-js: 1.2.1 - "@vue/compiler-ssr@3.5.30": + '@vue/compiler-ssr@3.5.30': dependencies: - "@vue/compiler-dom": 3.5.30 - "@vue/shared": 3.5.30 + '@vue/compiler-dom': 3.5.30 + '@vue/shared': 3.5.30 - "@vue/devtools-api@8.1.0": + '@vue/devtools-api@8.1.0': dependencies: - "@vue/devtools-kit": 8.1.0 + '@vue/devtools-kit': 8.1.0 - "@vue/devtools-kit@8.1.0": + '@vue/devtools-kit@8.1.0': dependencies: - "@vue/devtools-shared": 8.1.0 + '@vue/devtools-shared': 8.1.0 birpc: 2.9.0 hookable: 5.5.3 perfect-debounce: 2.1.0 - "@vue/devtools-shared@8.1.0": {} + '@vue/devtools-shared@8.1.0': {} - "@vue/reactivity@3.5.30": + '@vue/reactivity@3.5.30': dependencies: - "@vue/shared": 3.5.30 + '@vue/shared': 3.5.30 - "@vue/runtime-core@3.5.30": + '@vue/runtime-core@3.5.30': dependencies: - "@vue/reactivity": 3.5.30 - "@vue/shared": 3.5.30 + '@vue/reactivity': 3.5.30 + '@vue/shared': 3.5.30 - "@vue/runtime-dom@3.5.30": + '@vue/runtime-dom@3.5.30': dependencies: - "@vue/reactivity": 3.5.30 - "@vue/runtime-core": 3.5.30 - "@vue/shared": 3.5.30 + '@vue/reactivity': 3.5.30 + '@vue/runtime-core': 3.5.30 + '@vue/shared': 3.5.30 csstype: 3.2.3 - "@vue/server-renderer@3.5.30(vue@3.5.30)": + '@vue/server-renderer@3.5.30(vue@3.5.30)': dependencies: - "@vue/compiler-ssr": 3.5.30 - "@vue/shared": 3.5.30 + '@vue/compiler-ssr': 3.5.30 + '@vue/shared': 3.5.30 vue: 3.5.30 - "@vue/shared@3.5.30": {} + '@vue/shared@3.5.30': {} - "@vueuse/core@14.2.1(vue@3.5.30)": + '@vueuse/core@14.2.1(vue@3.5.30)': dependencies: - "@types/web-bluetooth": 0.0.21 - "@vueuse/metadata": 14.2.1 - "@vueuse/shared": 14.2.1(vue@3.5.30) + '@types/web-bluetooth': 0.0.21 + '@vueuse/metadata': 14.2.1 + '@vueuse/shared': 14.2.1(vue@3.5.30) vue: 3.5.30 - "@vueuse/integrations@14.2.1(focus-trap@7.8.0)(vue@3.5.30)": + '@vueuse/integrations@14.2.1(focus-trap@7.8.0)(vue@3.5.30)': dependencies: - "@vueuse/core": 14.2.1(vue@3.5.30) - "@vueuse/shared": 14.2.1(vue@3.5.30) + '@vueuse/core': 14.2.1(vue@3.5.30) + '@vueuse/shared': 14.2.1(vue@3.5.30) vue: 3.5.30 optionalDependencies: focus-trap: 7.8.0 - "@vueuse/metadata@14.2.1": {} + '@vueuse/metadata@14.2.1': {} - "@vueuse/shared@14.2.1(vue@3.5.30)": + '@vueuse/shared@14.2.1(vue@3.5.30)': dependencies: vue: 3.5.30 @@ -1929,32 +1335,32 @@ snapshots: esbuild@0.27.4: optionalDependencies: - "@esbuild/aix-ppc64": 0.27.4 - "@esbuild/android-arm": 0.27.4 - "@esbuild/android-arm64": 0.27.4 - "@esbuild/android-x64": 0.27.4 - "@esbuild/darwin-arm64": 0.27.4 - "@esbuild/darwin-x64": 0.27.4 - "@esbuild/freebsd-arm64": 0.27.4 - "@esbuild/freebsd-x64": 0.27.4 - "@esbuild/linux-arm": 0.27.4 - "@esbuild/linux-arm64": 0.27.4 - "@esbuild/linux-ia32": 0.27.4 - "@esbuild/linux-loong64": 0.27.4 - "@esbuild/linux-mips64el": 0.27.4 - "@esbuild/linux-ppc64": 0.27.4 - "@esbuild/linux-riscv64": 0.27.4 - "@esbuild/linux-s390x": 0.27.4 - "@esbuild/linux-x64": 0.27.4 - "@esbuild/netbsd-arm64": 0.27.4 - "@esbuild/netbsd-x64": 0.27.4 - "@esbuild/openbsd-arm64": 0.27.4 - "@esbuild/openbsd-x64": 0.27.4 - "@esbuild/openharmony-arm64": 0.27.4 - "@esbuild/sunos-x64": 0.27.4 - "@esbuild/win32-arm64": 0.27.4 - "@esbuild/win32-ia32": 0.27.4 - "@esbuild/win32-x64": 0.27.4 + '@esbuild/aix-ppc64': 0.27.4 + '@esbuild/android-arm': 0.27.4 + '@esbuild/android-arm64': 0.27.4 + '@esbuild/android-x64': 0.27.4 + '@esbuild/darwin-arm64': 0.27.4 + '@esbuild/darwin-x64': 0.27.4 + '@esbuild/freebsd-arm64': 0.27.4 + '@esbuild/freebsd-x64': 0.27.4 + '@esbuild/linux-arm': 0.27.4 + '@esbuild/linux-arm64': 0.27.4 + '@esbuild/linux-ia32': 0.27.4 + '@esbuild/linux-loong64': 0.27.4 + '@esbuild/linux-mips64el': 0.27.4 + '@esbuild/linux-ppc64': 0.27.4 + '@esbuild/linux-riscv64': 0.27.4 + '@esbuild/linux-s390x': 0.27.4 + '@esbuild/linux-x64': 0.27.4 + '@esbuild/netbsd-arm64': 0.27.4 + '@esbuild/netbsd-x64': 0.27.4 + '@esbuild/openbsd-arm64': 0.27.4 + '@esbuild/openbsd-x64': 0.27.4 + '@esbuild/openharmony-arm64': 0.27.4 + '@esbuild/sunos-x64': 0.27.4 + '@esbuild/win32-arm64': 0.27.4 + '@esbuild/win32-ia32': 0.27.4 + '@esbuild/win32-x64': 0.27.4 esprima@4.0.1: {} @@ -1998,8 +1404,8 @@ snapshots: hast-util-to-html@9.0.5: dependencies: - "@types/hast": 3.0.4 - "@types/unist": 3.0.3 + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 ccount: 2.0.1 comma-separated-tokens: 2.0.3 hast-util-whitespace: 3.0.0 @@ -2012,7 +1418,7 @@ snapshots: hast-util-whitespace@3.0.0: dependencies: - "@types/hast": 3.0.4 + '@types/hast': 3.0.4 hookable@5.5.3: {} @@ -2026,7 +1432,7 @@ snapshots: jackspeak@4.1.1: dependencies: - "@isaacs/cliui": 8.0.2 + '@isaacs/cliui': 8.0.2 js-yaml@3.14.2: dependencies: @@ -2039,15 +1445,15 @@ snapshots: magic-string@0.30.21: dependencies: - "@jridgewell/sourcemap-codec": 1.5.5 + '@jridgewell/sourcemap-codec': 1.5.5 mark.js@8.11.1: {} mdast-util-to-hast@13.2.1: dependencies: - "@types/hast": 3.0.4 - "@types/mdast": 4.0.4 - "@ungap/structured-clone": 1.3.0 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@ungap/structured-clone': 1.3.0 devlop: 1.1.0 micromark-util-sanitize-uri: 2.0.1 trim-lines: 3.0.1 @@ -2074,7 +1480,7 @@ snapshots: minimatch@10.1.1: dependencies: - "@isaacs/brace-expansion": 5.0.0 + '@isaacs/brace-expansion': 5.0.0 minipass@7.1.2: {} @@ -2127,33 +1533,33 @@ snapshots: rollup@4.59.0: dependencies: - "@types/estree": 1.0.8 + '@types/estree': 1.0.8 optionalDependencies: - "@rollup/rollup-android-arm-eabi": 4.59.0 - "@rollup/rollup-android-arm64": 4.59.0 - "@rollup/rollup-darwin-arm64": 4.59.0 - "@rollup/rollup-darwin-x64": 4.59.0 - "@rollup/rollup-freebsd-arm64": 4.59.0 - "@rollup/rollup-freebsd-x64": 4.59.0 - "@rollup/rollup-linux-arm-gnueabihf": 4.59.0 - "@rollup/rollup-linux-arm-musleabihf": 4.59.0 - "@rollup/rollup-linux-arm64-gnu": 4.59.0 - "@rollup/rollup-linux-arm64-musl": 4.59.0 - "@rollup/rollup-linux-loong64-gnu": 4.59.0 - "@rollup/rollup-linux-loong64-musl": 4.59.0 - "@rollup/rollup-linux-ppc64-gnu": 4.59.0 - "@rollup/rollup-linux-ppc64-musl": 4.59.0 - "@rollup/rollup-linux-riscv64-gnu": 4.59.0 - "@rollup/rollup-linux-riscv64-musl": 4.59.0 - "@rollup/rollup-linux-s390x-gnu": 4.59.0 - "@rollup/rollup-linux-x64-gnu": 4.59.0 - "@rollup/rollup-linux-x64-musl": 4.59.0 - "@rollup/rollup-openbsd-x64": 4.59.0 - "@rollup/rollup-openharmony-arm64": 4.59.0 - "@rollup/rollup-win32-arm64-msvc": 4.59.0 - "@rollup/rollup-win32-ia32-msvc": 4.59.0 - "@rollup/rollup-win32-x64-gnu": 4.59.0 - "@rollup/rollup-win32-x64-msvc": 4.59.0 + '@rollup/rollup-android-arm-eabi': 4.59.0 + '@rollup/rollup-android-arm64': 4.59.0 + '@rollup/rollup-darwin-arm64': 4.59.0 + '@rollup/rollup-darwin-x64': 4.59.0 + '@rollup/rollup-freebsd-arm64': 4.59.0 + '@rollup/rollup-freebsd-x64': 4.59.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.59.0 + '@rollup/rollup-linux-arm-musleabihf': 4.59.0 + '@rollup/rollup-linux-arm64-gnu': 4.59.0 + '@rollup/rollup-linux-arm64-musl': 4.59.0 + '@rollup/rollup-linux-loong64-gnu': 4.59.0 + '@rollup/rollup-linux-loong64-musl': 4.59.0 + '@rollup/rollup-linux-ppc64-gnu': 4.59.0 + '@rollup/rollup-linux-ppc64-musl': 4.59.0 + '@rollup/rollup-linux-riscv64-gnu': 4.59.0 + '@rollup/rollup-linux-riscv64-musl': 4.59.0 + '@rollup/rollup-linux-s390x-gnu': 4.59.0 + '@rollup/rollup-linux-x64-gnu': 4.59.0 + '@rollup/rollup-linux-x64-musl': 4.59.0 + '@rollup/rollup-openbsd-x64': 4.59.0 + '@rollup/rollup-openharmony-arm64': 4.59.0 + '@rollup/rollup-win32-arm64-msvc': 4.59.0 + '@rollup/rollup-win32-ia32-msvc': 4.59.0 + '@rollup/rollup-win32-x64-gnu': 4.59.0 + '@rollup/rollup-win32-x64-msvc': 4.59.0 fsevents: 2.3.3 section-matter@1.0.0: @@ -2169,14 +1575,14 @@ snapshots: shiki@3.23.0: dependencies: - "@shikijs/core": 3.23.0 - "@shikijs/engine-javascript": 3.23.0 - "@shikijs/engine-oniguruma": 3.23.0 - "@shikijs/langs": 3.23.0 - "@shikijs/themes": 3.23.0 - "@shikijs/types": 3.23.0 - "@shikijs/vscode-textmate": 10.0.2 - "@types/hast": 3.0.4 + '@shikijs/core': 3.23.0 + '@shikijs/engine-javascript': 3.23.0 + '@shikijs/engine-oniguruma': 3.23.0 + '@shikijs/langs': 3.23.0 + '@shikijs/themes': 3.23.0 + '@shikijs/types': 3.23.0 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 signal-exit@4.1.0: {} @@ -2224,35 +1630,35 @@ snapshots: unist-util-is@6.0.1: dependencies: - "@types/unist": 3.0.3 + '@types/unist': 3.0.3 unist-util-position@5.0.0: dependencies: - "@types/unist": 3.0.3 + '@types/unist': 3.0.3 unist-util-stringify-position@4.0.0: dependencies: - "@types/unist": 3.0.3 + '@types/unist': 3.0.3 unist-util-visit-parents@6.0.2: dependencies: - "@types/unist": 3.0.3 + '@types/unist': 3.0.3 unist-util-is: 6.0.1 unist-util-visit@5.1.0: dependencies: - "@types/unist": 3.0.3 + '@types/unist': 3.0.3 unist-util-is: 6.0.1 unist-util-visit-parents: 6.0.2 vfile-message@4.0.3: dependencies: - "@types/unist": 3.0.3 + '@types/unist': 3.0.3 unist-util-stringify-position: 4.0.0 vfile@6.0.3: dependencies: - "@types/unist": 3.0.3 + '@types/unist': 3.0.3 vfile-message: 4.0.3 vite@7.3.1: @@ -2274,19 +1680,19 @@ snapshots: vitepress@2.0.0-alpha.16(postcss@8.5.8): dependencies: - "@docsearch/css": 4.6.0 - "@docsearch/js": 4.6.0 - "@docsearch/sidepanel-js": 4.6.0 - "@iconify-json/simple-icons": 1.2.74 - "@shikijs/core": 3.23.0 - "@shikijs/transformers": 3.23.0 - "@shikijs/types": 3.23.0 - "@types/markdown-it": 14.1.2 - "@vitejs/plugin-vue": 6.0.5(vite@7.3.1)(vue@3.5.30) - "@vue/devtools-api": 8.1.0 - "@vue/shared": 3.5.30 - "@vueuse/core": 14.2.1(vue@3.5.30) - "@vueuse/integrations": 14.2.1(focus-trap@7.8.0)(vue@3.5.30) + '@docsearch/css': 4.6.0 + '@docsearch/js': 4.6.0 + '@docsearch/sidepanel-js': 4.6.0 + '@iconify-json/simple-icons': 1.2.74 + '@shikijs/core': 3.23.0 + '@shikijs/transformers': 3.23.0 + '@shikijs/types': 3.23.0 + '@types/markdown-it': 14.1.2 + '@vitejs/plugin-vue': 6.0.5(vite@7.3.1)(vue@3.5.30) + '@vue/devtools-api': 8.1.0 + '@vue/shared': 3.5.30 + '@vueuse/core': 14.2.1(vue@3.5.30) + '@vueuse/integrations': 14.2.1(focus-trap@7.8.0)(vue@3.5.30) focus-trap: 7.8.0 mark.js: 8.11.1 minisearch: 7.2.0 @@ -2296,7 +1702,7 @@ snapshots: optionalDependencies: postcss: 8.5.8 transitivePeerDependencies: - - "@types/node" + - '@types/node' - async-validator - axios - change-case @@ -2322,11 +1728,11 @@ snapshots: vue@3.5.30: dependencies: - "@vue/compiler-dom": 3.5.30 - "@vue/compiler-sfc": 3.5.30 - "@vue/runtime-dom": 3.5.30 - "@vue/server-renderer": 3.5.30(vue@3.5.30) - "@vue/shared": 3.5.30 + '@vue/compiler-dom': 3.5.30 + '@vue/compiler-sfc': 3.5.30 + '@vue/runtime-dom': 3.5.30 + '@vue/server-renderer': 3.5.30(vue@3.5.30) + '@vue/shared': 3.5.30 which@2.0.2: dependencies: From 2c7527c121af21ff81ca53f82c92bb99fc8bedfc Mon Sep 17 00:00:00 2001 From: RocketQuack <202538874+Rocket-Quack@users.noreply.github.com> Date: Thu, 19 Mar 2026 12:25:24 +0100 Subject: [PATCH 175/279] chore(pre-commit): exclude docs pnpm lockfile from prettier --- .pre-commit-config.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ef57978e..67863a8c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -27,6 +27,7 @@ repos: rev: v4.0.0-alpha.8 hooks: - id: prettier + exclude: ^docs/pnpm-lock\.yaml$ additional_dependencies: - prettier@3.5.2 From 20c040c25b630f641c7167304a3872bc68556a8c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 20 Mar 2026 08:22:28 +0000 Subject: [PATCH 176/279] chore(deps): bump pnpm/action-setup from 4 to 5 Bumps [pnpm/action-setup](https://github.com/pnpm/action-setup) from 4 to 5. - [Release notes](https://github.com/pnpm/action-setup/releases) - [Commits](https://github.com/pnpm/action-setup/compare/v4...v5) --- updated-dependencies: - dependency-name: pnpm/action-setup dependency-version: '5' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/publish_docs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish_docs.yml b/.github/workflows/publish_docs.yml index d2f6c2b2..f37a66e9 100644 --- a/.github/workflows/publish_docs.yml +++ b/.github/workflows/publish_docs.yml @@ -33,7 +33,7 @@ jobs: uses: actions/checkout@v6 - name: Install pnpm - uses: pnpm/action-setup@v4 + uses: pnpm/action-setup@v5 with: version: 10 From 316c02bd884ea66d79c61386619f3da2607dce9b Mon Sep 17 00:00:00 2001 From: github-actions Date: Mon, 23 Mar 2026 17:02:54 +0000 Subject: [PATCH 177/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 344e2b21..ba4d57db 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v16.10.1 +ERPNEXT_VERSION=v16.11.0 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index 9415d066..05edef79 100644 --- a/pwd.yml +++ b/pwd.yml @@ -1,6 +1,6 @@ services: backend: - image: frappe/erpnext:v16.10.1 + image: frappe/erpnext:v16.11.0 networks: - frappe_network deploy: @@ -16,7 +16,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v16.10.1 + image: frappe/erpnext:v16.11.0 networks: - frappe_network deploy: @@ -45,7 +45,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v16.10.1 + image: frappe/erpnext:v16.11.0 networks: - frappe_network deploy: @@ -100,7 +100,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v16.10.1 + image: frappe/erpnext:v16.11.0 networks: - frappe_network depends_on: @@ -126,7 +126,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v16.10.1 + image: frappe/erpnext:v16.11.0 networks: - frappe_network deploy: @@ -145,7 +145,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v16.10.1 + image: frappe/erpnext:v16.11.0 networks: - frappe_network deploy: @@ -182,7 +182,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v16.10.1 + image: frappe/erpnext:v16.11.0 networks: - frappe_network deploy: @@ -196,7 +196,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v16.10.1 + image: frappe/erpnext:v16.11.0 networks: - frappe_network deploy: From 51e3fa8a463f8b4ee21cdcdf2fe8c53edc81435e Mon Sep 17 00:00:00 2001 From: Trusted Computer <75872475+trustedcomputer@users.noreply.github.com> Date: Tue, 24 Mar 2026 18:48:20 -0700 Subject: [PATCH 178/279] fix: copy security_headers.conf before chown --- images/custom/Containerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/images/custom/Containerfile b/images/custom/Containerfile index b72af438..a8298b52 100644 --- a/images/custom/Containerfile +++ b/images/custom/Containerfile @@ -4,6 +4,7 @@ FROM python:${PYTHON_VERSION}-slim-${DEBIAN_BASE} AS base COPY resources/core/nginx/nginx-template.conf /templates/nginx/frappe.conf.template COPY resources/core/nginx/nginx-entrypoint.sh /usr/local/bin/nginx-entrypoint.sh +COPY resources/core/nginx/security_headers.conf /etc/nginx/snippets/security_headers.conf ARG WKHTMLTOPDF_VERSION=0.12.6.1-3 ARG WKHTMLTOPDF_DISTRO=bookworm @@ -78,7 +79,6 @@ RUN useradd -ms /bin/bash frappe \ && chmod 755 /usr/local/bin/nginx-entrypoint.sh \ && chmod 644 /templates/nginx/frappe.conf.template -COPY resources/core/nginx/security_headers.conf /etc/nginx/snippets/security_headers.conf FROM base AS builder From 60a27952c9a9381c92e9df1ae5b167d436eb1737 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 26 Mar 2026 08:22:38 +0000 Subject: [PATCH 179/279] chore(deps): bump actions/deploy-pages from 4 to 5 Bumps [actions/deploy-pages](https://github.com/actions/deploy-pages) from 4 to 5. - [Release notes](https://github.com/actions/deploy-pages/releases) - [Commits](https://github.com/actions/deploy-pages/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/deploy-pages dependency-version: '5' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/publish_docs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish_docs.yml b/.github/workflows/publish_docs.yml index f37a66e9..ab9de0ef 100644 --- a/.github/workflows/publish_docs.yml +++ b/.github/workflows/publish_docs.yml @@ -57,4 +57,4 @@ jobs: - name: Deploy to GitHub Pages id: deployment - uses: actions/deploy-pages@v4 + uses: actions/deploy-pages@v5 From 8ccccdbdd59b3207b72418dfac022ed26a81c1dd Mon Sep 17 00:00:00 2001 From: Daniel Radl Date: Mon, 30 Mar 2026 12:08:46 +0200 Subject: [PATCH 180/279] fix: nginx redirects leak internal port --- resources/core/nginx/nginx-template.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/core/nginx/nginx-template.conf b/resources/core/nginx/nginx-template.conf index 2172ebb7..7594a9a4 100644 --- a/resources/core/nginx/nginx-template.conf +++ b/resources/core/nginx/nginx-template.conf @@ -15,6 +15,7 @@ map $http_x_forwarded_proto $proxy_x_forwarded_proto { server { listen 8080; server_name ${FRAPPE_SITE_NAME_HEADER}; + port_in_redirect off; root /home/frappe/frappe-bench/sites; proxy_buffer_size 128k; From 40c741b751b1a88da4e4f815c9ae6620f03b1f28 Mon Sep 17 00:00:00 2001 From: github-actions Date: Mon, 30 Mar 2026 18:30:39 +0000 Subject: [PATCH 181/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index ba4d57db..38fc15ae 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md -ERPNEXT_VERSION=v16.11.0 +ERPNEXT_VERSION=v16.12.0 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index 05edef79..103d3969 100644 --- a/pwd.yml +++ b/pwd.yml @@ -1,6 +1,6 @@ services: backend: - image: frappe/erpnext:v16.11.0 + image: frappe/erpnext:v16.12.0 networks: - frappe_network deploy: @@ -16,7 +16,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v16.11.0 + image: frappe/erpnext:v16.12.0 networks: - frappe_network deploy: @@ -45,7 +45,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v16.11.0 + image: frappe/erpnext:v16.12.0 networks: - frappe_network deploy: @@ -100,7 +100,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v16.11.0 + image: frappe/erpnext:v16.12.0 networks: - frappe_network depends_on: @@ -126,7 +126,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v16.11.0 + image: frappe/erpnext:v16.12.0 networks: - frappe_network deploy: @@ -145,7 +145,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v16.11.0 + image: frappe/erpnext:v16.12.0 networks: - frappe_network deploy: @@ -182,7 +182,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v16.11.0 + image: frappe/erpnext:v16.12.0 networks: - frappe_network deploy: @@ -196,7 +196,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v16.11.0 + image: frappe/erpnext:v16.12.0 networks: - frappe_network deploy: From eccae398c597a7332529232ce42743e6b80abf30 Mon Sep 17 00:00:00 2001 From: Daniel Radl Date: Tue, 31 Mar 2026 16:40:41 +0200 Subject: [PATCH 182/279] fix(nginx): set absolute_redirect off --- resources/core/nginx/nginx-template.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/core/nginx/nginx-template.conf b/resources/core/nginx/nginx-template.conf index 7594a9a4..b7626b5e 100644 --- a/resources/core/nginx/nginx-template.conf +++ b/resources/core/nginx/nginx-template.conf @@ -15,7 +15,7 @@ map $http_x_forwarded_proto $proxy_x_forwarded_proto { server { listen 8080; server_name ${FRAPPE_SITE_NAME_HEADER}; - port_in_redirect off; + absolute_redirect off; root /home/frappe/frappe-bench/sites; proxy_buffer_size 128k; From 1b105dac84cb96d26f162a50b909f34ad6cccfde Mon Sep 17 00:00:00 2001 From: RocketQuack <202538874+Rocket-Quack@users.noreply.github.com> Date: Wed, 1 Apr 2026 17:45:49 +0200 Subject: [PATCH 183/279] fix(docs): override vulnerable brace-expansion dependency --- docs/package.json | 5 +++++ docs/pnpm-lock.yaml | 11 +++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/docs/package.json b/docs/package.json index 91fd37bb..3a277b34 100644 --- a/docs/package.json +++ b/docs/package.json @@ -8,5 +8,10 @@ "docs:build": "vitepress build", "docs:preview": "vitepress preview" }, + "pnpm": { + "overrides": { + "@isaacs/brace-expansion": "5.0.1" + } + }, "packageManager": "pnpm@10.28.2+sha512.41872f037ad22f7348e3b1debbaf7e867cfd448f2726d9cf74c08f19507c31d2c8e7a11525b983febc2df640b5438dee6023ebb1f84ed43cc2d654d2bc326264" } diff --git a/docs/pnpm-lock.yaml b/docs/pnpm-lock.yaml index 7dbba065..64c297e9 100644 --- a/docs/pnpm-lock.yaml +++ b/docs/pnpm-lock.yaml @@ -4,6 +4,9 @@ settings: autoInstallPeers: true excludeLinksFromLockfile: false +overrides: + '@isaacs/brace-expansion': 5.0.1 + importers: .: @@ -209,8 +212,8 @@ packages: resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} engines: {node: 20 || >=22} - '@isaacs/brace-expansion@5.0.0': - resolution: {integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==} + '@isaacs/brace-expansion@5.0.1': + resolution: {integrity: sha512-WMz71T1JS624nWj2n2fnYAuPovhv7EUhk69R6i9dsVyzxt5eM3bjwvgk9L+APE1TRscGysAVMANkB0jh0LQZrQ==} engines: {node: 20 || >=22} '@isaacs/cliui@8.0.2': @@ -1032,7 +1035,7 @@ snapshots: '@isaacs/balanced-match@4.0.1': {} - '@isaacs/brace-expansion@5.0.0': + '@isaacs/brace-expansion@5.0.1': dependencies: '@isaacs/balanced-match': 4.0.1 @@ -1480,7 +1483,7 @@ snapshots: minimatch@10.1.1: dependencies: - '@isaacs/brace-expansion': 5.0.0 + '@isaacs/brace-expansion': 5.0.1 minipass@7.1.2: {} From 3c076d0eccccb2e49e7163a6e8c6cd82bd92cb4a Mon Sep 17 00:00:00 2001 From: RocketQuack <202538874+Rocket-Quack@users.noreply.github.com> Date: Wed, 1 Apr 2026 19:25:51 +0200 Subject: [PATCH 184/279] fix(docs): override vulnerable minimatch and picomatch --- docs/package.json | 3 ++- docs/pnpm-lock.yaml | 63 +++++++++++++++++++++++---------------------- 2 files changed, 34 insertions(+), 32 deletions(-) diff --git a/docs/package.json b/docs/package.json index 3a277b34..5a0481aa 100644 --- a/docs/package.json +++ b/docs/package.json @@ -10,7 +10,8 @@ }, "pnpm": { "overrides": { - "@isaacs/brace-expansion": "5.0.1" + "minimatch": "10.2.5", + "picomatch": "4.0.4" } }, "packageManager": "pnpm@10.28.2+sha512.41872f037ad22f7348e3b1debbaf7e867cfd448f2726d9cf74c08f19507c31d2c8e7a11525b983febc2df640b5438dee6023ebb1f84ed43cc2d654d2bc326264" diff --git a/docs/pnpm-lock.yaml b/docs/pnpm-lock.yaml index 64c297e9..500375b9 100644 --- a/docs/pnpm-lock.yaml +++ b/docs/pnpm-lock.yaml @@ -5,7 +5,8 @@ settings: excludeLinksFromLockfile: false overrides: - '@isaacs/brace-expansion': 5.0.1 + minimatch: 10.2.5 + picomatch: 4.0.4 importers: @@ -208,14 +209,6 @@ packages: '@iconify/types@2.0.0': resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} - '@isaacs/balanced-match@4.0.1': - resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} - engines: {node: 20 || >=22} - - '@isaacs/brace-expansion@5.0.1': - resolution: {integrity: sha512-WMz71T1JS624nWj2n2fnYAuPovhv7EUhk69R6i9dsVyzxt5eM3bjwvgk9L+APE1TRscGysAVMANkB0jh0LQZrQ==} - engines: {node: 20 || >=22} - '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} @@ -534,9 +527,17 @@ packages: argparse@1.0.10: resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + balanced-match@4.0.4: + resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} + engines: {node: 18 || 20 || >=22} + birpc@2.9.0: resolution: {integrity: sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw==} + brace-expansion@5.0.5: + resolution: {integrity: sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==} + engines: {node: 18 || 20 || >=22} + ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} @@ -604,7 +605,7 @@ packages: resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} engines: {node: '>=12.0.0'} peerDependencies: - picomatch: ^3 || ^4 + picomatch: 4.0.4 peerDependenciesMeta: picomatch: optional: true @@ -694,9 +695,9 @@ packages: micromark-util-types@2.0.2: resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} - minimatch@10.1.1: - resolution: {integrity: sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==} - engines: {node: 20 || >=22} + minimatch@10.2.5: + resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==} + engines: {node: 18 || 20 || >=22} minipass@7.1.2: resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} @@ -733,8 +734,8 @@ packages: picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} - picomatch@4.0.3: - resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} + picomatch@4.0.4: + resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} engines: {node: '>=12'} postcss@8.5.8: @@ -1033,12 +1034,6 @@ snapshots: '@iconify/types@2.0.0': {} - '@isaacs/balanced-match@4.0.1': {} - - '@isaacs/brace-expansion@5.0.1': - dependencies: - '@isaacs/balanced-match': 4.0.1 - '@isaacs/cliui@8.0.2': dependencies: string-width: 5.1.2 @@ -1298,8 +1293,14 @@ snapshots: dependencies: sprintf-js: 1.0.3 + balanced-match@4.0.4: {} + birpc@2.9.0: {} + brace-expansion@5.0.5: + dependencies: + balanced-match: 4.0.4 + ccount@2.0.1: {} character-entities-html4@2.1.0: {} @@ -1373,9 +1374,9 @@ snapshots: dependencies: is-extendable: 0.1.1 - fdir@6.5.0(picomatch@4.0.3): + fdir@6.5.0(picomatch@4.0.4): optionalDependencies: - picomatch: 4.0.3 + picomatch: 4.0.4 focus-trap@7.8.0: dependencies: @@ -1393,7 +1394,7 @@ snapshots: dependencies: foreground-child: 3.3.1 jackspeak: 4.1.1 - minimatch: 10.1.1 + minimatch: 10.2.5 minipass: 7.1.2 package-json-from-dist: 1.0.1 path-scurry: 2.0.1 @@ -1481,9 +1482,9 @@ snapshots: micromark-util-types@2.0.2: {} - minimatch@10.1.1: + minimatch@10.2.5: dependencies: - '@isaacs/brace-expansion': 5.0.1 + brace-expansion: 5.0.5 minipass@7.1.2: {} @@ -1512,7 +1513,7 @@ snapshots: picocolors@1.1.1: {} - picomatch@4.0.3: {} + picomatch@4.0.4: {} postcss@8.5.8: dependencies: @@ -1626,8 +1627,8 @@ snapshots: tinyglobby@0.2.15: dependencies: - fdir: 6.5.0(picomatch@4.0.3) - picomatch: 4.0.3 + fdir: 6.5.0(picomatch@4.0.4) + picomatch: 4.0.4 trim-lines@3.0.1: {} @@ -1667,8 +1668,8 @@ snapshots: vite@7.3.1: dependencies: esbuild: 0.27.4 - fdir: 6.5.0(picomatch@4.0.3) - picomatch: 4.0.3 + fdir: 6.5.0(picomatch@4.0.4) + picomatch: 4.0.4 postcss: 8.5.8 rollup: 4.59.0 tinyglobby: 0.2.15 From 8d83c2dd04f5f038ea5440b4bca42e820d69268b Mon Sep 17 00:00:00 2001 From: RocketQuack <202538874+Rocket-Quack@users.noreply.github.com> Date: Wed, 1 Apr 2026 19:44:12 +0200 Subject: [PATCH 185/279] fix(docs): correct single compose setup home link --- docs/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.md b/docs/index.md index 3a108011..854b9768 100644 --- a/docs/index.md +++ b/docs/index.md @@ -14,7 +14,7 @@ hero: link: /getting-started - theme: alt text: Single Compose Setup - link: /01-getting-started/02-single-compose-setup + link: /01-getting-started/04-single-compose-setup features: - title: Containerised From 6c05252b9f13e57e4b3302683b9d4e012bc53b55 Mon Sep 17 00:00:00 2001 From: ews-pgasser Date: Thu, 2 Apr 2026 10:00:33 +0200 Subject: [PATCH 186/279] chore: update frappe branch to version-16 --- development/installer.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/development/installer.py b/development/installer.py index edd62147..cb6b774a 100755 --- a/development/installer.py +++ b/development/installer.py @@ -72,8 +72,8 @@ def get_args_parser(): "--frappe-branch", action="store", type=str, - help="frappe repo to use, default: version-15", # noqa: E501 - default="version-15", + help="frappe repo to use, default: version-16", # noqa: E501 + default="version-16", ) parser.add_argument( "-p", From fc604799694021b461cc1fd6e7d42df1f6d62640 Mon Sep 17 00:00:00 2001 From: ews-pgasser Date: Thu, 2 Apr 2026 10:00:40 +0200 Subject: [PATCH 187/279] chore: update erpnext branch to version-16 --- development/apps-example.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/development/apps-example.json b/development/apps-example.json index 513d3d10..d629a08c 100644 --- a/development/apps-example.json +++ b/development/apps-example.json @@ -1,6 +1,6 @@ [ { "url": "https://github.com/frappe/erpnext.git", - "branch": "version-15" + "branch": "version-16" } -] +] \ No newline at end of file From 023af5214cdb2dbdb65bf2f2c9ab5541af071fcc Mon Sep 17 00:00:00 2001 From: Daniel Radl Date: Thu, 2 Apr 2026 13:48:10 +0200 Subject: [PATCH 188/279] chore: add EOF newline --- development/apps-example.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/development/apps-example.json b/development/apps-example.json index d629a08c..c68f7f58 100644 --- a/development/apps-example.json +++ b/development/apps-example.json @@ -3,4 +3,4 @@ "url": "https://github.com/frappe/erpnext.git", "branch": "version-16" } -] \ No newline at end of file +] From c1236d9fcf7144fde71a03d05840637de4fe9577 Mon Sep 17 00:00:00 2001 From: ews-pgasser Date: Thu, 2 Apr 2026 16:01:41 +0200 Subject: [PATCH 189/279] feat: add pre-commit to devcontainer postCreateCommand --- devcontainer-example/devcontainer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/devcontainer-example/devcontainer.json b/devcontainer-example/devcontainer.json index c5fceddc..192b91f4 100644 --- a/devcontainer-example/devcontainer.json +++ b/devcontainer-example/devcontainer.json @@ -44,6 +44,7 @@ "service": "frappe", "workspaceFolder": "/workspace/development", "shutdownAction": "stopCompose", + "postCreateCommand": "uv tool install pre-commit", "mounts": [ "source=${localEnv:HOME}${localEnv:USERPROFILE}/.ssh,target=/home/frappe/.ssh,type=bind,consistency=cached" ] From c7d61a5a6dd5a3c70497fa702b17adf12214785e Mon Sep 17 00:00:00 2001 From: Roger Saner Date: Thu, 2 Apr 2026 18:43:23 +0200 Subject: [PATCH 190/279] fix: update example.env Correct link to env vars doc --- example.env | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example.env b/example.env index 38fc15ae..d9044b77 100644 --- a/example.env +++ b/example.env @@ -1,4 +1,4 @@ -# Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md +# Reference: https://github.com/frappe/frappe_docker/blob/main/docs/02-setup/04-env-variables.md ERPNEXT_VERSION=v16.12.0 From 563e895ad05316723899e88ca1a09fd1c0f09686 Mon Sep 17 00:00:00 2001 From: Roger Saner Date: Thu, 2 Apr 2026 18:55:05 +0200 Subject: [PATCH 191/279] fix: update compose.yaml Correct URL for Build Setup --- compose.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compose.yaml b/compose.yaml index c1f2eb63..5920e6d3 100644 --- a/compose.yaml +++ b/compose.yaml @@ -1,6 +1,6 @@ x-customizable-image: &customizable_image # By default the image used only contains the `frappe` and `erpnext` apps. - # See https://github.com/frappe/frappe_docker/blob/main/docs/container-setup/02-build-setup.md#define-custom-apps + # See https://github.com/frappe/frappe_docker/blob/main/docs/02-setup/02-build-setup.md#define-custom-apps # about using custom images. image: ${CUSTOM_IMAGE:-frappe/erpnext}:${CUSTOM_TAG:-$ERPNEXT_VERSION} pull_policy: ${PULL_POLICY:-always} From 259aa24c6497be7fad20766f4401df1deb5db17d Mon Sep 17 00:00:00 2001 From: Sujal Singh Date: Sat, 4 Apr 2026 06:44:45 +0530 Subject: [PATCH 192/279] docs: fix dead link for environment variables reference --- example.env | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example.env b/example.env index 38fc15ae..d9044b77 100644 --- a/example.env +++ b/example.env @@ -1,4 +1,4 @@ -# Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md +# Reference: https://github.com/frappe/frappe_docker/blob/main/docs/02-setup/04-env-variables.md ERPNEXT_VERSION=v16.12.0 From ae275df16173dd2778146fc241baef7cb9ffabae Mon Sep 17 00:00:00 2001 From: OmarElaraby26 Date: Sun, 5 Apr 2026 22:24:53 +0200 Subject: [PATCH 193/279] fix(security): replace APPS_JSON_BASE64 build-arg with BuildKit secret mount APPS_JSON_BASE64 is stored in image layer metadata, permanently exposing private repo tokens (GitHub PATs) to anyone with image pull access. Replace --build-arg with --mount=type=secret so that apps.json is only available during the RUN step and never committed to any layer. Refs: https://docs.docker.com/reference/build-checks/secrets-used-in-arg-or-env/ --- docs/02-setup/02-build-setup.md | 16 ++++++---------- .../08-single-server-nginxproxy-example.md | 14 +++----------- images/custom/Containerfile | 13 ++++++------- images/layered/Containerfile | 14 ++++++-------- 4 files changed, 21 insertions(+), 36 deletions(-) diff --git a/docs/02-setup/02-build-setup.md b/docs/02-setup/02-build-setup.md index 93331280..1ffa35d9 100644 --- a/docs/02-setup/02-build-setup.md +++ b/docs/02-setup/02-build-setup.md @@ -42,23 +42,19 @@ To include custom apps in your image, create an `apps.json` file in the reposito ] ``` -Then generate a base64-encoded string from this file: - -```bash -export APPS_JSON_BASE64=$(base64 -w 0 apps.json) -``` - # Build the image Choose the appropriate build command based on your container runtime and desired image type. This example builds the `layered` image with the custom `apps.json` you created. +> **Security note:** The `apps.json` file is passed as a [BuildKit secret](https://docs.docker.com/build/building/secrets/) so that private repository tokens are **never** stored in image layer metadata. Do not use `--build-arg` for `apps.json` β€” build arguments are permanently visible via `docker image history`. + `Docker`: ```bash -docker build \ +DOCKER_BUILDKIT=1 docker build \ --build-arg=FRAPPE_PATH=https://github.com/frappe/frappe \ --build-arg=FRAPPE_BRANCH=version-15 \ - --build-arg=APPS_JSON_BASE64=$APPS_JSON_BASE64 \ + --secret=id=apps_json,src=apps.json \ --tag=custom:15 \ --file=images/layered/Containerfile . ``` @@ -69,7 +65,7 @@ docker build \ podman build \ --build-arg=FRAPPE_PATH=https://github.com/frappe/frappe \ --build-arg=FRAPPE_BRANCH=version-15 \ - --build-arg=APPS_JSON_BASE64=$APPS_JSON_BASE64 \ + --secret=id=apps_json,src=apps.json \ --tag=custom:15 \ --file=images/layered/Containerfile . ``` @@ -82,7 +78,7 @@ podman build \ | FRAPPE_PATH | Repository URL for Frappe framework source code. Defaults to https://github.com/frappe/frappe | | FRAPPE_BRANCH | Branch to use for Frappe framework. Defaults to version-15 | | **Custom Apps** | | -| APPS_JSON_BASE64 | Base64-encoded JSON string from apps.json defining apps to install | +| (secret) apps_json | Passed via `--secret=id=apps_json,src=apps.json`. Never use `--build-arg` for this file. | | **Dependencies** | | | PYTHON_VERSION | Python version for the base image | | NODE_VERSION | Node.js version | diff --git a/docs/02-setup/08-single-server-nginxproxy-example.md b/docs/02-setup/08-single-server-nginxproxy-example.md index 0049e39f..2cef110d 100644 --- a/docs/02-setup/08-single-server-nginxproxy-example.md +++ b/docs/02-setup/08-single-server-nginxproxy-example.md @@ -84,25 +84,17 @@ cat > ~/gitops/apps.json <<'EOF' EOF ``` -Generate the BASE64 value and build: +Build the image, passing `apps.json` as a [BuildKit secret](https://docs.docker.com/build/building/secrets/) so that private repo tokens are never stored in image layers: ```shell -export APPS_JSON_BASE64=$(base64 -w 0 ~/gitops/apps.json) - -docker build \ +DOCKER_BUILDKIT=1 docker build \ --build-arg=FRAPPE_PATH=https://github.com/frappe/frappe \ --build-arg=FRAPPE_BRANCH=version-16 \ - --build-arg=APPS_JSON_BASE64=$APPS_JSON_BASE64 \ + --secret=id=apps_json,src=$HOME/gitops/apps.json \ --tag=my-erpnext-prod-image:16.0.0 \ --file=images/layered/Containerfile . ``` -If `base64 -w 0` is not available on your system, use: - -```shell -export APPS_JSON_BASE64=$(base64 ~/gitops/apps.json | tr -d '\n') -``` - ### Configure environment Create an environment file for the bench: diff --git a/images/custom/Containerfile b/images/custom/Containerfile index a8298b52..8a4a58b2 100644 --- a/images/custom/Containerfile +++ b/images/custom/Containerfile @@ -113,18 +113,17 @@ RUN apt-get update \ libbz2-dev \ && rm -rf /var/lib/apt/lists/* -# apps.json includes -ARG APPS_JSON_BASE64 -RUN if [ -n "${APPS_JSON_BASE64}" ]; then \ - mkdir /opt/frappe && echo "${APPS_JSON_BASE64}" | base64 -d > /opt/frappe/apps.json; \ - fi +# apps.json is passed as a BuildKit secret so that private repo tokens +# are never baked into any image layer. The secret is mounted only for +# this RUN step and is not present in the final image. USER frappe ARG FRAPPE_BRANCH=version-16 ARG FRAPPE_PATH=https://github.com/frappe/frappe -RUN export APP_INSTALL_ARGS="" && \ - if [ -n "${APPS_JSON_BASE64}" ]; then \ +RUN --mount=type=secret,id=apps_json,target=/opt/frappe/apps.json,uid=1000,gid=1000 \ + export APP_INSTALL_ARGS="" && \ + if [ -f /opt/frappe/apps.json ] && [ -s /opt/frappe/apps.json ]; then \ export APP_INSTALL_ARGS="--apps_path=/opt/frappe/apps.json"; \ fi && \ bench init ${APP_INSTALL_ARGS}\ diff --git a/images/layered/Containerfile b/images/layered/Containerfile index 142c487a..117ab1ab 100644 --- a/images/layered/Containerfile +++ b/images/layered/Containerfile @@ -4,18 +4,16 @@ FROM frappe/build:${FRAPPE_BRANCH} AS builder ARG FRAPPE_BRANCH=version-16 ARG FRAPPE_PATH=https://github.com/frappe/frappe -ARG APPS_JSON_BASE64 -USER root - -RUN if [ -n "${APPS_JSON_BASE64}" ]; then \ - mkdir /opt/frappe && echo "${APPS_JSON_BASE64}" | base64 -d > /opt/frappe/apps.json; \ - fi +# apps.json is passed as a BuildKit secret so that private repo tokens +# are never baked into any image layer. The secret is mounted only for +# this RUN step and is not present in the final image. USER frappe -RUN export APP_INSTALL_ARGS="" && \ - if [ -n "${APPS_JSON_BASE64}" ]; then \ +RUN --mount=type=secret,id=apps_json,target=/opt/frappe/apps.json,uid=1000,gid=1000 \ + export APP_INSTALL_ARGS="" && \ + if [ -f /opt/frappe/apps.json ] && [ -s /opt/frappe/apps.json ]; then \ export APP_INSTALL_ARGS="--apps_path=/opt/frappe/apps.json"; \ fi && \ bench init ${APP_INSTALL_ARGS}\ From 8892908f5d3041d4c9383702265d88b4c8a08687 Mon Sep 17 00:00:00 2001 From: OmarElaraby26 Date: Tue, 7 Apr 2026 20:12:29 +0200 Subject: [PATCH 194/279] docs: require Docker Engine v23+ instead of setting DOCKER_BUILDKIT=1 BuildKit has been the default builder since Docker Engine 23.0 (Feb 2023), so prefixing the example build commands with DOCKER_BUILDKIT=1 is redundant on any supported install. Replace the prefix with an explicit prerequisite note so the requirement lives with the user's environment, not the example. The build relies on BuildKit secret mounts (--secret) to keep apps.json tokens out of image layers, which is why a real BuildKit-default engine is mandatory rather than merely recommended. Addresses review feedback on PR #1861. --- docs/02-setup/02-build-setup.md | 8 +++++--- docs/02-setup/08-single-server-nginxproxy-example.md | 6 +++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/docs/02-setup/02-build-setup.md b/docs/02-setup/02-build-setup.md index 1ffa35d9..d411cab7 100644 --- a/docs/02-setup/02-build-setup.md +++ b/docs/02-setup/02-build-setup.md @@ -7,11 +7,13 @@ This guide walks you through building Frappe images from the repository resource # Prerequisites - git -- docker or podman +- docker (Engine **v23.0+**) or podman - docker compose v2 or podman compose > Install containerization software according to the official maintainer documentation. Avoid package managers when not recommended, as they frequently cause compatibility issues. +> **Why Docker Engine v23+?** The build uses [BuildKit secrets](https://docs.docker.com/build/building/secrets/) (`--secret`) to keep `apps.json` tokens out of image layers. BuildKit is the default builder starting with Docker Engine 23.0 β€” older releases will fail or silently fall back to the legacy builder, which does not support secret mounts. + # Clone this repo ```bash @@ -46,12 +48,12 @@ To include custom apps in your image, create an `apps.json` file in the reposito Choose the appropriate build command based on your container runtime and desired image type. This example builds the `layered` image with the custom `apps.json` you created. -> **Security note:** The `apps.json` file is passed as a [BuildKit secret](https://docs.docker.com/build/building/secrets/) so that private repository tokens are **never** stored in image layer metadata. Do not use `--build-arg` for `apps.json` β€” build arguments are permanently visible via `docker image history`. +> **Security note:** The `apps.json` file is passed as a [BuildKit secret](https://docs.docker.com/build/building/secrets/) so that private repository tokens are **never** stored in image layer metadata. Do not use `--build-arg` for `apps.json` β€” build arguments are permanently visible via `docker image history`. This requires **Docker Engine v23.0+** (where BuildKit is the default builder). `Docker`: ```bash -DOCKER_BUILDKIT=1 docker build \ +docker build \ --build-arg=FRAPPE_PATH=https://github.com/frappe/frappe \ --build-arg=FRAPPE_BRANCH=version-15 \ --secret=id=apps_json,src=apps.json \ diff --git a/docs/02-setup/08-single-server-nginxproxy-example.md b/docs/02-setup/08-single-server-nginxproxy-example.md index 2cef110d..4f1c212f 100644 --- a/docs/02-setup/08-single-server-nginxproxy-example.md +++ b/docs/02-setup/08-single-server-nginxproxy-example.md @@ -15,7 +15,7 @@ We will setup the following: ## Requirements -- A server that can run Docker (recommended: 2 vCPU, 4 GB RAM, 50 GB SSD). +- A server that can run Docker Engine **v23.0+** (recommended: 2 vCPU, 4 GB RAM, 50 GB SSD). The custom-image build below uses [BuildKit secrets](https://docs.docker.com/build/building/secrets/), which require BuildKit as the default builder (Docker Engine 23.0+). - A public domain with DNS control. - Two subdomains pointing to your server IP (A/AAAA records): - `erp.your-domain.com` @@ -84,10 +84,10 @@ cat > ~/gitops/apps.json <<'EOF' EOF ``` -Build the image, passing `apps.json` as a [BuildKit secret](https://docs.docker.com/build/building/secrets/) so that private repo tokens are never stored in image layers: +Build the image, passing `apps.json` as a [BuildKit secret](https://docs.docker.com/build/building/secrets/) so that private repo tokens are never stored in image layers. This requires **Docker Engine v23.0+**, where BuildKit is the default builder: ```shell -DOCKER_BUILDKIT=1 docker build \ +docker build \ --build-arg=FRAPPE_PATH=https://github.com/frappe/frappe \ --build-arg=FRAPPE_BRANCH=version-16 \ --secret=id=apps_json,src=$HOME/gitops/apps.json \ From 031d1964a1e1e31901b388d875e35cf1077fa056 Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 7 Apr 2026 18:26:31 +0000 Subject: [PATCH 195/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index d9044b77..0973d04d 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/02-setup/04-env-variables.md -ERPNEXT_VERSION=v16.12.0 +ERPNEXT_VERSION=v16.13.0 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index 103d3969..56c1adce 100644 --- a/pwd.yml +++ b/pwd.yml @@ -1,6 +1,6 @@ services: backend: - image: frappe/erpnext:v16.12.0 + image: frappe/erpnext:v16.13.0 networks: - frappe_network deploy: @@ -16,7 +16,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v16.12.0 + image: frappe/erpnext:v16.13.0 networks: - frappe_network deploy: @@ -45,7 +45,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v16.12.0 + image: frappe/erpnext:v16.13.0 networks: - frappe_network deploy: @@ -100,7 +100,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v16.12.0 + image: frappe/erpnext:v16.13.0 networks: - frappe_network depends_on: @@ -126,7 +126,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v16.12.0 + image: frappe/erpnext:v16.13.0 networks: - frappe_network deploy: @@ -145,7 +145,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v16.12.0 + image: frappe/erpnext:v16.13.0 networks: - frappe_network deploy: @@ -182,7 +182,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v16.12.0 + image: frappe/erpnext:v16.13.0 networks: - frappe_network deploy: @@ -196,7 +196,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v16.12.0 + image: frappe/erpnext:v16.13.0 networks: - frappe_network deploy: From f521624b1b4be5024b8a8ae36a1585ef4f7c5b81 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 Apr 2026 08:24:16 +0000 Subject: [PATCH 196/279] chore(deps): bump pytest from 9.0.2 to 9.0.3 Bumps [pytest](https://github.com/pytest-dev/pytest) from 9.0.2 to 9.0.3. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/9.0.2...9.0.3) --- updated-dependencies: - dependency-name: pytest dependency-version: 9.0.3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements-test.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-test.txt b/requirements-test.txt index 5b240e09..b3b2b3ca 100644 --- a/requirements-test.txt +++ b/requirements-test.txt @@ -1 +1 @@ -pytest==9.0.2 +pytest==9.0.3 From 20169854f5c943e6cc060e21eeeeda98d2d9f903 Mon Sep 17 00:00:00 2001 From: github-actions Date: Thu, 9 Apr 2026 05:17:52 +0000 Subject: [PATCH 197/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 0973d04d..66171756 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/02-setup/04-env-variables.md -ERPNEXT_VERSION=v16.13.0 +ERPNEXT_VERSION=v16.13.1 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index 56c1adce..9fa623f4 100644 --- a/pwd.yml +++ b/pwd.yml @@ -1,6 +1,6 @@ services: backend: - image: frappe/erpnext:v16.13.0 + image: frappe/erpnext:v16.13.1 networks: - frappe_network deploy: @@ -16,7 +16,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v16.13.0 + image: frappe/erpnext:v16.13.1 networks: - frappe_network deploy: @@ -45,7 +45,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v16.13.0 + image: frappe/erpnext:v16.13.1 networks: - frappe_network deploy: @@ -100,7 +100,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v16.13.0 + image: frappe/erpnext:v16.13.1 networks: - frappe_network depends_on: @@ -126,7 +126,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v16.13.0 + image: frappe/erpnext:v16.13.1 networks: - frappe_network deploy: @@ -145,7 +145,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v16.13.0 + image: frappe/erpnext:v16.13.1 networks: - frappe_network deploy: @@ -182,7 +182,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v16.13.0 + image: frappe/erpnext:v16.13.1 networks: - frappe_network deploy: @@ -196,7 +196,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v16.13.0 + image: frappe/erpnext:v16.13.1 networks: - frappe_network deploy: From dfb6ee4f088e0fe48f3b4d21af53856424faaf72 Mon Sep 17 00:00:00 2001 From: github-actions Date: Thu, 9 Apr 2026 10:37:09 +0000 Subject: [PATCH 198/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 66171756..2e6864aa 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/02-setup/04-env-variables.md -ERPNEXT_VERSION=v16.13.1 +ERPNEXT_VERSION=v16.13.2 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index 9fa623f4..a0259f04 100644 --- a/pwd.yml +++ b/pwd.yml @@ -1,6 +1,6 @@ services: backend: - image: frappe/erpnext:v16.13.1 + image: frappe/erpnext:v16.13.2 networks: - frappe_network deploy: @@ -16,7 +16,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v16.13.1 + image: frappe/erpnext:v16.13.2 networks: - frappe_network deploy: @@ -45,7 +45,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v16.13.1 + image: frappe/erpnext:v16.13.2 networks: - frappe_network deploy: @@ -100,7 +100,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v16.13.1 + image: frappe/erpnext:v16.13.2 networks: - frappe_network depends_on: @@ -126,7 +126,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v16.13.1 + image: frappe/erpnext:v16.13.2 networks: - frappe_network deploy: @@ -145,7 +145,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v16.13.1 + image: frappe/erpnext:v16.13.2 networks: - frappe_network deploy: @@ -182,7 +182,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v16.13.1 + image: frappe/erpnext:v16.13.2 networks: - frappe_network deploy: @@ -196,7 +196,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v16.13.1 + image: frappe/erpnext:v16.13.2 networks: - frappe_network deploy: From 90d9d25eb3a9ac41353c0d2547a04b3e32cfd3f7 Mon Sep 17 00:00:00 2001 From: RocketQuack <202538874+Rocket-Quack@users.noreply.github.com> Date: Thu, 9 Apr 2026 13:17:52 +0200 Subject: [PATCH 199/279] fix(docs): override vulnerable vite dependency --- docs/package.json | 1 + docs/pnpm-lock.yaml | 17 +++++++++-------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/docs/package.json b/docs/package.json index 5a0481aa..153ee463 100644 --- a/docs/package.json +++ b/docs/package.json @@ -10,6 +10,7 @@ }, "pnpm": { "overrides": { + "vite": "7.3.2", "minimatch": "10.2.5", "picomatch": "4.0.4" } diff --git a/docs/pnpm-lock.yaml b/docs/pnpm-lock.yaml index 500375b9..2e0b4ee7 100644 --- a/docs/pnpm-lock.yaml +++ b/docs/pnpm-lock.yaml @@ -5,6 +5,7 @@ settings: excludeLinksFromLockfile: false overrides: + vite: 7.3.2 minimatch: 10.2.5 picomatch: 4.0.4 @@ -412,7 +413,7 @@ packages: resolution: {integrity: sha512-bL3AxKuQySfk1iGcBsQnoRVexTPJq0Z/ixFVM8OhVJAP6ZXXXLtM7NFKWhLl30Kg7uTBqIaPXbh+nuQCuBDedg==} engines: {node: ^20.19.0 || >=22.12.0} peerDependencies: - vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 + vite: 7.3.2 vue: ^3.2.25 '@vue/compiler-core@3.5.30': @@ -846,8 +847,8 @@ packages: vfile@6.0.3: resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} - vite@7.3.1: - resolution: {integrity: sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==} + vite@7.3.2: + resolution: {integrity: sha512-Bby3NOsna2jsjfLVOHKes8sGwgl4TT0E6vvpYgnAYDIF/tie7MRaFthmKuHx1NSXjiTueXH3do80FMQgvEktRg==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: @@ -1185,10 +1186,10 @@ snapshots: '@ungap/structured-clone@1.3.0': {} - '@vitejs/plugin-vue@6.0.5(vite@7.3.1)(vue@3.5.30)': + '@vitejs/plugin-vue@6.0.5(vite@7.3.2)(vue@3.5.30)': dependencies: '@rolldown/pluginutils': 1.0.0-rc.2 - vite: 7.3.1 + vite: 7.3.2 vue: 3.5.30 '@vue/compiler-core@3.5.30': @@ -1665,7 +1666,7 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.3 - vite@7.3.1: + vite@7.3.2: dependencies: esbuild: 0.27.4 fdir: 6.5.0(picomatch@4.0.4) @@ -1692,7 +1693,7 @@ snapshots: '@shikijs/transformers': 3.23.0 '@shikijs/types': 3.23.0 '@types/markdown-it': 14.1.2 - '@vitejs/plugin-vue': 6.0.5(vite@7.3.1)(vue@3.5.30) + '@vitejs/plugin-vue': 6.0.5(vite@7.3.2)(vue@3.5.30) '@vue/devtools-api': 8.1.0 '@vue/shared': 3.5.30 '@vueuse/core': 14.2.1(vue@3.5.30) @@ -1701,7 +1702,7 @@ snapshots: mark.js: 8.11.1 minisearch: 7.2.0 shiki: 3.23.0 - vite: 7.3.1 + vite: 7.3.2 vue: 3.5.30 optionalDependencies: postcss: 8.5.8 From 91308ce43d2d469362b47b2158b0faac8f0176b4 Mon Sep 17 00:00:00 2001 From: Daniel Radl Date: Fri, 10 Apr 2026 16:51:19 +0200 Subject: [PATCH 200/279] chore(vscode): exclude build artifacts and deps from file watcher --- development/vscode-example/settings.json | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/development/vscode-example/settings.json b/development/vscode-example/settings.json index 1490b727..e89d2005 100644 --- a/development/vscode-example/settings.json +++ b/development/vscode-example/settings.json @@ -1,3 +1,19 @@ { - "python.defaultInterpreterPath": "${workspaceFolder}/frappe-bench/env/bin/python" + "python.defaultInterpreterPath": "${workspaceFolder}/frappe-bench/env/bin/python", + "files.watcherExclude": { + // --- Node modules --- + "**/node_modules/**": true, + + // --- Frappe bench core dirs --- + "**/env/**": true, + "**/config/**": true, + + // --- Build artifacts --- + "**/__pycache__/**": true, + "**/*.pyc": true + }, + "files.exclude": { + "**/__pycache__": true, + "**/*.pyc": true + } } From f36bde7acab2879110436985f311f9be7907e6bb Mon Sep 17 00:00:00 2001 From: github-actions Date: Sat, 11 Apr 2026 05:32:15 +0000 Subject: [PATCH 201/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 2e6864aa..5eaeaa7d 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/02-setup/04-env-variables.md -ERPNEXT_VERSION=v16.13.2 +ERPNEXT_VERSION=v16.13.3 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index a0259f04..0564d09b 100644 --- a/pwd.yml +++ b/pwd.yml @@ -1,6 +1,6 @@ services: backend: - image: frappe/erpnext:v16.13.2 + image: frappe/erpnext:v16.13.3 networks: - frappe_network deploy: @@ -16,7 +16,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v16.13.2 + image: frappe/erpnext:v16.13.3 networks: - frappe_network deploy: @@ -45,7 +45,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v16.13.2 + image: frappe/erpnext:v16.13.3 networks: - frappe_network deploy: @@ -100,7 +100,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v16.13.2 + image: frappe/erpnext:v16.13.3 networks: - frappe_network depends_on: @@ -126,7 +126,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v16.13.2 + image: frappe/erpnext:v16.13.3 networks: - frappe_network deploy: @@ -145,7 +145,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v16.13.2 + image: frappe/erpnext:v16.13.3 networks: - frappe_network deploy: @@ -182,7 +182,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v16.13.2 + image: frappe/erpnext:v16.13.3 networks: - frappe_network deploy: @@ -196,7 +196,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v16.13.2 + image: frappe/erpnext:v16.13.3 networks: - frappe_network deploy: From adaf37dfa58f7cc4a100fa5643df431531551647 Mon Sep 17 00:00:00 2001 From: Daniel Radl Date: Sun, 12 Apr 2026 15:06:17 +0200 Subject: [PATCH 202/279] docs: add MAINTAINERS.md to document project maintainers --- MAINTAINERS.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 MAINTAINERS.md diff --git a/MAINTAINERS.md b/MAINTAINERS.md new file mode 100644 index 00000000..b4afca59 --- /dev/null +++ b/MAINTAINERS.md @@ -0,0 +1,25 @@ +# Maintainers + +This project is actively maintained by the following people. + +Maintainers are responsible for: + +- Reviewing and merging pull requests +- Managing releases +- Triaging and responding to issues +- Ensuring the overall health and direction of the project + +## Current Maintainers + +- [@revant](https://github.com/revant) +- [@DanielRadlAMR](https://github.com/DanielRadlAMR) +- [@Rocket-Quack](https://github.com/Rocket-Quack) + +## Emeritus Maintainers + +_(none)_ + +## Becoming a Maintainer + +Contributors who consistently help review pull requests, participate in issue triage, +and contribute to releases may be invited to become maintainers. From 526119247fc7940d0bbecb74de751854906a9a4e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Apr 2026 08:39:30 +0000 Subject: [PATCH 203/279] chore(deps): bump docker/bake-action from 7.0.0 to 7.1.0 Bumps [docker/bake-action](https://github.com/docker/bake-action) from 7.0.0 to 7.1.0. - [Release notes](https://github.com/docker/bake-action/releases) - [Commits](https://github.com/docker/bake-action/compare/v7.0.0...v7.1.0) --- updated-dependencies: - dependency-name: docker/bake-action dependency-version: 7.1.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/build_bench.yml | 4 ++-- .github/workflows/docker-build-push.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build_bench.yml b/.github/workflows/build_bench.yml index 257a31c1..1bc47018 100644 --- a/.github/workflows/build_bench.yml +++ b/.github/workflows/build_bench.yml @@ -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@v7.0.0 + uses: docker/bake-action@v7.1.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@v7.0.0 + uses: docker/bake-action@v7.1.0 with: targets: bench push: true diff --git a/.github/workflows/docker-build-push.yml b/.github/workflows/docker-build-push.yml index 376118cd..9fee1782 100644 --- a/.github/workflows/docker-build-push.yml +++ b/.github/workflows/docker-build-push.yml @@ -66,7 +66,7 @@ jobs: echo "NODE_VERSION=${{ inputs.node_version }}" >> "$GITHUB_ENV" - name: Build - uses: docker/bake-action@v7.0.0 + uses: docker/bake-action@v7.1.0 with: source: . push: true @@ -95,7 +95,7 @@ jobs: - name: Push if: ${{ inputs.push }} - uses: docker/bake-action@v7.0.0 + uses: docker/bake-action@v7.1.0 with: push: true set: "*.platform=linux/amd64,linux/arm64" From 3e1e045f7a0ad28c1719770ebb27f1b0337613b4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Apr 2026 08:39:38 +0000 Subject: [PATCH 204/279] chore(deps): bump pnpm/action-setup from 5 to 6 Bumps [pnpm/action-setup](https://github.com/pnpm/action-setup) from 5 to 6. - [Release notes](https://github.com/pnpm/action-setup/releases) - [Commits](https://github.com/pnpm/action-setup/compare/v5...v6) --- updated-dependencies: - dependency-name: pnpm/action-setup dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/publish_docs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish_docs.yml b/.github/workflows/publish_docs.yml index ab9de0ef..8aa04ea7 100644 --- a/.github/workflows/publish_docs.yml +++ b/.github/workflows/publish_docs.yml @@ -33,7 +33,7 @@ jobs: uses: actions/checkout@v6 - name: Install pnpm - uses: pnpm/action-setup@v5 + uses: pnpm/action-setup@v6 with: version: 10 From db8868b25b899ddcf3037ab34a4ec978bf61bd93 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 14 Apr 2026 08:23:11 +0000 Subject: [PATCH 205/279] chore(deps): bump actions/upload-pages-artifact from 4 to 5 Bumps [actions/upload-pages-artifact](https://github.com/actions/upload-pages-artifact) from 4 to 5. - [Release notes](https://github.com/actions/upload-pages-artifact/releases) - [Commits](https://github.com/actions/upload-pages-artifact/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/upload-pages-artifact dependency-version: '5' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/publish_docs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish_docs.yml b/.github/workflows/publish_docs.yml index ab9de0ef..94812ac0 100644 --- a/.github/workflows/publish_docs.yml +++ b/.github/workflows/publish_docs.yml @@ -51,7 +51,7 @@ jobs: run: pnpm docs:build - name: Upload artifact - uses: actions/upload-pages-artifact@v4 + uses: actions/upload-pages-artifact@v5 with: path: docs/.vitepress/dist From 169d5be00ce15529b5f2833cdb8023b5a56964b9 Mon Sep 17 00:00:00 2001 From: RocketQuack <202538874+Rocket-Quack@users.noreply.github.com> Date: Tue, 14 Apr 2026 13:49:21 +0200 Subject: [PATCH 206/279] ci(docs): pin pnpm version for pages build --- .github/workflows/publish_docs.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish_docs.yml b/.github/workflows/publish_docs.yml index 31a72e4a..130c3402 100644 --- a/.github/workflows/publish_docs.yml +++ b/.github/workflows/publish_docs.yml @@ -35,14 +35,14 @@ jobs: - name: Install pnpm uses: pnpm/action-setup@v6 with: - version: 10 + version: 10.28.2 - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v6 with: node-version: ${{ matrix.node-version }} cache: "pnpm" - cache-dependency-path: ./docs + cache-dependency-path: ./docs/pnpm-lock.yaml - name: Install dependencies run: pnpm i --frozen-lockfile From 0feb49d00a2d2534efcc1895e99a99e8c502cd1a Mon Sep 17 00:00:00 2001 From: RocketQuack <202538874+Rocket-Quack@users.noreply.github.com> Date: Tue, 14 Apr 2026 13:55:29 +0200 Subject: [PATCH 207/279] ci(docs): add lockfile debug output for pages workflow --- .github/workflows/publish_docs.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/.github/workflows/publish_docs.yml b/.github/workflows/publish_docs.yml index 130c3402..4b52f9e8 100644 --- a/.github/workflows/publish_docs.yml +++ b/.github/workflows/publish_docs.yml @@ -44,6 +44,23 @@ jobs: cache: "pnpm" cache-dependency-path: ./docs/pnpm-lock.yaml + - name: Debug lockfile on runner + run: | + pwd + ls -la + echo "sha256 (workspace file):" + sha256sum pnpm-lock.yaml + echo "sha256 (git blob at HEAD):" + git show HEAD:docs/pnpm-lock.yaml | sha256sum + echo "lockfileVersion count:" + grep -c '^lockfileVersion:' pnpm-lock.yaml || true + echo "yaml document markers:" + grep -nE '^---$|^\\.\\.\\.$|^<<<<<<<|^=======|^>>>>>>>$' pnpm-lock.yaml || true + echo "first 20 lines:" + sed -n '1,20p' pnpm-lock.yaml + echo "last 20 lines:" + tail -n 20 pnpm-lock.yaml + - name: Install dependencies run: pnpm i --frozen-lockfile From 1d957628157f66cba6daa1dd54b7b2c955390feb Mon Sep 17 00:00:00 2001 From: RocketQuack <202538874+Rocket-Quack@users.noreply.github.com> Date: Tue, 14 Apr 2026 14:02:04 +0200 Subject: [PATCH 208/279] ci(docs): switch pages workflow to corepack-managed pnpm --- .github/workflows/publish_docs.yml | 31 +++++++++++------------------- 1 file changed, 11 insertions(+), 20 deletions(-) diff --git a/.github/workflows/publish_docs.yml b/.github/workflows/publish_docs.yml index 4b52f9e8..adbac6ea 100644 --- a/.github/workflows/publish_docs.yml +++ b/.github/workflows/publish_docs.yml @@ -32,11 +32,6 @@ jobs: - name: Checkout uses: actions/checkout@v6 - - name: Install pnpm - uses: pnpm/action-setup@v6 - with: - version: 10.28.2 - - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v6 with: @@ -44,22 +39,18 @@ jobs: cache: "pnpm" cache-dependency-path: ./docs/pnpm-lock.yaml - - name: Debug lockfile on runner + - name: Enable Corepack + run: corepack enable + + - name: Activate pnpm + run: corepack prepare pnpm@10.28.2 --activate + + - name: Show tool versions run: | - pwd - ls -la - echo "sha256 (workspace file):" - sha256sum pnpm-lock.yaml - echo "sha256 (git blob at HEAD):" - git show HEAD:docs/pnpm-lock.yaml | sha256sum - echo "lockfileVersion count:" - grep -c '^lockfileVersion:' pnpm-lock.yaml || true - echo "yaml document markers:" - grep -nE '^---$|^\\.\\.\\.$|^<<<<<<<|^=======|^>>>>>>>$' pnpm-lock.yaml || true - echo "first 20 lines:" - sed -n '1,20p' pnpm-lock.yaml - echo "last 20 lines:" - tail -n 20 pnpm-lock.yaml + node --version + corepack --version + pnpm --version + which pnpm - name: Install dependencies run: pnpm i --frozen-lockfile From adc72561a148b5e315bb48a9cafda43160765b65 Mon Sep 17 00:00:00 2001 From: RocketQuack <202538874+Rocket-Quack@users.noreply.github.com> Date: Tue, 14 Apr 2026 14:04:05 +0200 Subject: [PATCH 209/279] ci(docs): remove setup-node pnpm cache for corepack flow --- .github/workflows/publish_docs.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/publish_docs.yml b/.github/workflows/publish_docs.yml index adbac6ea..ffecb82c 100644 --- a/.github/workflows/publish_docs.yml +++ b/.github/workflows/publish_docs.yml @@ -36,8 +36,6 @@ jobs: uses: actions/setup-node@v6 with: node-version: ${{ matrix.node-version }} - cache: "pnpm" - cache-dependency-path: ./docs/pnpm-lock.yaml - name: Enable Corepack run: corepack enable From 616ffd417797031f760e7a6c9669923a5febed66 Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 14 Apr 2026 18:46:14 +0000 Subject: [PATCH 210/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 5eaeaa7d..5471b7dc 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/02-setup/04-env-variables.md -ERPNEXT_VERSION=v16.13.3 +ERPNEXT_VERSION=v16.14.0 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index 0564d09b..612344db 100644 --- a/pwd.yml +++ b/pwd.yml @@ -1,6 +1,6 @@ services: backend: - image: frappe/erpnext:v16.13.3 + image: frappe/erpnext:v16.14.0 networks: - frappe_network deploy: @@ -16,7 +16,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v16.13.3 + image: frappe/erpnext:v16.14.0 networks: - frappe_network deploy: @@ -45,7 +45,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v16.13.3 + image: frappe/erpnext:v16.14.0 networks: - frappe_network deploy: @@ -100,7 +100,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v16.13.3 + image: frappe/erpnext:v16.14.0 networks: - frappe_network depends_on: @@ -126,7 +126,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v16.13.3 + image: frappe/erpnext:v16.14.0 networks: - frappe_network deploy: @@ -145,7 +145,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v16.13.3 + image: frappe/erpnext:v16.14.0 networks: - frappe_network deploy: @@ -182,7 +182,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v16.13.3 + image: frappe/erpnext:v16.14.0 networks: - frappe_network deploy: @@ -196,7 +196,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v16.13.3 + image: frappe/erpnext:v16.14.0 networks: - frappe_network deploy: From 1fe7523bfbf43202911f531c86d772833cb3bf95 Mon Sep 17 00:00:00 2001 From: Daniel Radl Date: Wed, 15 Apr 2026 12:44:03 +0200 Subject: [PATCH 211/279] chore(vscode): show git folder --- development/vscode-example/settings.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/development/vscode-example/settings.json b/development/vscode-example/settings.json index e89d2005..cfc5b0f7 100644 --- a/development/vscode-example/settings.json +++ b/development/vscode-example/settings.json @@ -14,6 +14,7 @@ }, "files.exclude": { "**/__pycache__": true, - "**/*.pyc": true + "**/*.pyc": true, + "**/.git": false } } From 4e5f84fa29a1e0bd1cbed3a57e36f5766421260c Mon Sep 17 00:00:00 2001 From: RocketQuack <202538874+Rocket-Quack@users.noreply.github.com> Date: Wed, 15 Apr 2026 13:52:31 +0200 Subject: [PATCH 212/279] chore: remove comments about why BuildKit is being used to parse apps.json --- images/custom/Containerfile | 4 ---- images/layered/Containerfile | 4 ---- 2 files changed, 8 deletions(-) diff --git a/images/custom/Containerfile b/images/custom/Containerfile index 8a4a58b2..c7519e84 100644 --- a/images/custom/Containerfile +++ b/images/custom/Containerfile @@ -113,10 +113,6 @@ RUN apt-get update \ libbz2-dev \ && rm -rf /var/lib/apt/lists/* -# apps.json is passed as a BuildKit secret so that private repo tokens -# are never baked into any image layer. The secret is mounted only for -# this RUN step and is not present in the final image. - USER frappe ARG FRAPPE_BRANCH=version-16 diff --git a/images/layered/Containerfile b/images/layered/Containerfile index 117ab1ab..de5e835d 100644 --- a/images/layered/Containerfile +++ b/images/layered/Containerfile @@ -5,10 +5,6 @@ FROM frappe/build:${FRAPPE_BRANCH} AS builder ARG FRAPPE_BRANCH=version-16 ARG FRAPPE_PATH=https://github.com/frappe/frappe -# apps.json is passed as a BuildKit secret so that private repo tokens -# are never baked into any image layer. The secret is mounted only for -# this RUN step and is not present in the final image. - USER frappe RUN --mount=type=secret,id=apps_json,target=/opt/frappe/apps.json,uid=1000,gid=1000 \ From 9cecbc7b2de8dc9d410ea30f7c34576a42f8b366 Mon Sep 17 00:00:00 2001 From: jslocomotor <210083531+jslocomotor@users.noreply.github.com> Date: Sat, 18 Apr 2026 21:18:22 +0200 Subject: [PATCH 213/279] chore(compose): use MariaDB 11.8 and remove obsolete MariaDB 10.6 workaround --- devcontainer-example/docker-compose.yml | 1 - docs/01-getting-started/03-arm64.md | 3 +-- overrides/compose.mariadb-shared.yaml | 1 - overrides/compose.mariadb.yaml | 1 - pwd.yml | 3 +-- 5 files changed, 2 insertions(+), 7 deletions(-) diff --git a/devcontainer-example/docker-compose.yml b/devcontainer-example/docker-compose.yml index 3c23b4f3..bf3bbf72 100644 --- a/devcontainer-example/docker-compose.yml +++ b/devcontainer-example/docker-compose.yml @@ -5,7 +5,6 @@ services: - --character-set-server=utf8mb4 - --collation-server=utf8mb4_unicode_ci - --skip-character-set-client-handshake - - --skip-innodb-read-only-compressed # Temporary fix for MariaDB 10.6 environment: MYSQL_ROOT_PASSWORD: 123 MARIADB_AUTO_UPGRADE: 1 diff --git a/docs/01-getting-started/03-arm64.md b/docs/01-getting-started/03-arm64.md index c76beb06..b9defd89 100644 --- a/docs/01-getting-started/03-arm64.md +++ b/docs/01-getting-started/03-arm64.md @@ -100,7 +100,7 @@ services: bench new-site --mariadb-user-host-login-scope=% --admin-password=admin --db-root-password=admin --install-app erpnext --set-default frontend; db: - image: mariadb:10.6 + image: mariadb:11.8 platform: linux/amd64 healthcheck: test: mysqladmin ping -h localhost --password=admin @@ -113,7 +113,6 @@ services: - --character-set-server=utf8mb4 - --collation-server=utf8mb4_unicode_ci - --skip-character-set-client-handshake - - --skip-innodb-read-only-compressed # Temporary fix for MariaDB 10.6 environment: MYSQL_ROOT_PASSWORD: admin volumes: diff --git a/overrides/compose.mariadb-shared.yaml b/overrides/compose.mariadb-shared.yaml index f28031c0..0c815007 100644 --- a/overrides/compose.mariadb-shared.yaml +++ b/overrides/compose.mariadb-shared.yaml @@ -13,7 +13,6 @@ services: - --character-set-server=utf8mb4 - --collation-server=utf8mb4_unicode_ci - --skip-character-set-client-handshake - - --skip-innodb-read-only-compressed environment: MYSQL_ROOT_PASSWORD: ${DB_PASSWORD:-changeit} MARIADB_AUTO_UPGRADE: 1 diff --git a/overrides/compose.mariadb.yaml b/overrides/compose.mariadb.yaml index e79288c0..94e177c3 100644 --- a/overrides/compose.mariadb.yaml +++ b/overrides/compose.mariadb.yaml @@ -20,7 +20,6 @@ services: - --character-set-server=utf8mb4 - --collation-server=utf8mb4_unicode_ci - --skip-character-set-client-handshake - - --skip-innodb-read-only-compressed # Temporary fix for MariaDB 10.6 environment: MYSQL_ROOT_PASSWORD: ${DB_PASSWORD:-123} MARIADB_AUTO_UPGRADE: 1 diff --git a/pwd.yml b/pwd.yml index 612344db..4cb9b474 100644 --- a/pwd.yml +++ b/pwd.yml @@ -78,7 +78,7 @@ services: bench new-site --mariadb-user-host-login-scope='%' --admin-password=admin --db-root-username=root --db-root-password=admin --install-app erpnext --set-default frontend; db: - image: mariadb:10.6 + image: mariadb:11.8 networks: - frappe_network healthcheck: @@ -92,7 +92,6 @@ services: - --character-set-server=utf8mb4 - --collation-server=utf8mb4_unicode_ci - --skip-character-set-client-handshake - - --skip-innodb-read-only-compressed # Temporary fix for MariaDB 10.6 environment: MYSQL_ROOT_PASSWORD: admin MARIADB_ROOT_PASSWORD: admin From 9ae698926929476213bbb3b9b4cb836b68856a73 Mon Sep 17 00:00:00 2001 From: ews-pgasser Date: Mon, 20 Apr 2026 15:34:55 +0200 Subject: [PATCH 214/279] fix: remove nested sites assets volume --- images/layered/Containerfile | 1 - 1 file changed, 1 deletion(-) diff --git a/images/layered/Containerfile b/images/layered/Containerfile index de5e835d..02bf9a20 100644 --- a/images/layered/Containerfile +++ b/images/layered/Containerfile @@ -34,7 +34,6 @@ WORKDIR /home/frappe/frappe-bench VOLUME [ \ "/home/frappe/frappe-bench/sites", \ - "/home/frappe/frappe-bench/sites/assets", \ "/home/frappe/frappe-bench/logs" \ ] From 0cddb6f35becbf9027f67058ef8ffcc74c505321 Mon Sep 17 00:00:00 2001 From: ews-pgasser Date: Mon, 20 Apr 2026 15:35:36 +0200 Subject: [PATCH 215/279] docs: document volume migration notes for sites/assets change --- docs/02-setup/02-build-setup.md | 39 +++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/docs/02-setup/02-build-setup.md b/docs/02-setup/02-build-setup.md index d411cab7..c4404d93 100644 --- a/docs/02-setup/02-build-setup.md +++ b/docs/02-setup/02-build-setup.md @@ -74,20 +74,20 @@ podman build \ ## Build args -| Arg | Purpose | -| -------------------- | --------------------------------------------------------------------------------------------- | -| **Frappe Framework** | | -| FRAPPE_PATH | Repository URL for Frappe framework source code. Defaults to https://github.com/frappe/frappe | -| FRAPPE_BRANCH | Branch to use for Frappe framework. Defaults to version-15 | -| **Custom Apps** | | -| (secret) apps_json | Passed via `--secret=id=apps_json,src=apps.json`. Never use `--build-arg` for this file. | -| **Dependencies** | | -| PYTHON_VERSION | Python version for the base image | -| NODE_VERSION | Node.js version | -| WKHTMLTOPDF_VERSION | wkhtmltopdf version | -| **bench only** | | -| DEBIAN_BASE | Debian base version for the bench image, defaults to `bookworm` | -| WKHTMLTOPDF_DISTRO | use the specified distro for debian package. Default is `bookworm` | +| Arg | Purpose | +| -------------------- | ----------------------------------------------------------------------------------------------- | +| **Frappe Framework** | | +| FRAPPE_PATH | Repository URL for Frappe framework source code. Defaults to | +| FRAPPE_BRANCH | Branch to use for Frappe framework. Defaults to version-15 | +| **Custom Apps** | | +| (secret) apps_json | Passed via `--secret=id=apps_json,src=apps.json`. Never use `--build-arg` for this file. | +| **Dependencies** | | +| PYTHON_VERSION | Python version for the base image | +| NODE_VERSION | Node.js version | +| WKHTMLTOPDF_VERSION | wkhtmltopdf version | +| **bench only** | | +| DEBIAN_BASE | Debian base version for the bench image, defaults to `bookworm` | +| WKHTMLTOPDF_DISTRO | use the specified distro for debian package. Default is `bookworm` | # env file @@ -130,6 +130,17 @@ This generates `compose.custom.yaml`, which you'll use to start all containers. > **NOTE**: podman compose is just a wrapper, it uses docker-compose if it is available or podman-compose if not. podman-compose have an issue reading .env files ([Issue](https://github.com/containers/podman-compose/issues/475)) and might create an issue when running the containers. +# Upgrading from images with a nested sites/assets volume + +Previous images declared `VOLUME /home/frappe/frappe-bench/sites/assets` separately. This created an implicit nested mountpoint inside the `sites` volume, which could cause Docker to attach different anonymous volumes per container in multi-container setups. +That declaration has been removed. `sites` is now the single shared mount, consistent with the compose setup and docs. + +**After pulling the updated image:** + +- Recreate all containers (`docker compose up --force-recreate`). Without this, Docker may keep the old anonymous `sites/assets` volume + attached from before the change. +- No `bench build` is needed β€” this only fixes mount consistency, not the asset workflow. + --- **Next:** [Start Setup β†’](03-start-setup.md) From 63f5169610e483770069061aa99040aeaaa13bce Mon Sep 17 00:00:00 2001 From: ews-pgasser Date: Mon, 20 Apr 2026 16:30:58 +0200 Subject: [PATCH 216/279] fix: removed sites/assets volume from custom & production Containerfile too --- images/custom/Containerfile | 1 - images/production/Containerfile | 1 - 2 files changed, 2 deletions(-) diff --git a/images/custom/Containerfile b/images/custom/Containerfile index c7519e84..e0c5b335 100644 --- a/images/custom/Containerfile +++ b/images/custom/Containerfile @@ -144,7 +144,6 @@ WORKDIR /home/frappe/frappe-bench VOLUME [ \ "/home/frappe/frappe-bench/sites", \ - "/home/frappe/frappe-bench/sites/assets", \ "/home/frappe/frappe-bench/logs" \ ] diff --git a/images/production/Containerfile b/images/production/Containerfile index 17f1573d..4dfb8685 100644 --- a/images/production/Containerfile +++ b/images/production/Containerfile @@ -137,7 +137,6 @@ WORKDIR /home/frappe/frappe-bench VOLUME [ \ "/home/frappe/frappe-bench/sites", \ - "/home/frappe/frappe-bench/sites/assets", \ "/home/frappe/frappe-bench/logs" \ ] From 17670ec04c34d2666bd82b819a43d8c01c1277f2 Mon Sep 17 00:00:00 2001 From: ews-pgasser Date: Mon, 20 Apr 2026 17:23:46 +0200 Subject: [PATCH 217/279] docs: move sites/assets volume upgrade note to migration docs --- docs/02-setup/02-build-setup.md | 11 ----------- .../06-migration/01-migrate-from-multi-image-setup.md | 11 +++++++++++ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/02-setup/02-build-setup.md b/docs/02-setup/02-build-setup.md index c4404d93..d0e6907b 100644 --- a/docs/02-setup/02-build-setup.md +++ b/docs/02-setup/02-build-setup.md @@ -130,17 +130,6 @@ This generates `compose.custom.yaml`, which you'll use to start all containers. > **NOTE**: podman compose is just a wrapper, it uses docker-compose if it is available or podman-compose if not. podman-compose have an issue reading .env files ([Issue](https://github.com/containers/podman-compose/issues/475)) and might create an issue when running the containers. -# Upgrading from images with a nested sites/assets volume - -Previous images declared `VOLUME /home/frappe/frappe-bench/sites/assets` separately. This created an implicit nested mountpoint inside the `sites` volume, which could cause Docker to attach different anonymous volumes per container in multi-container setups. -That declaration has been removed. `sites` is now the single shared mount, consistent with the compose setup and docs. - -**After pulling the updated image:** - -- Recreate all containers (`docker compose up --force-recreate`). Without this, Docker may keep the old anonymous `sites/assets` volume - attached from before the change. -- No `bench build` is needed β€” this only fixes mount consistency, not the asset workflow. - --- **Next:** [Start Setup β†’](03-start-setup.md) diff --git a/docs/06-migration/01-migrate-from-multi-image-setup.md b/docs/06-migration/01-migrate-from-multi-image-setup.md index 0fd2e344..04d8a2c1 100644 --- a/docs/06-migration/01-migrate-from-multi-image-setup.md +++ b/docs/06-migration/01-migrate-from-multi-image-setup.md @@ -114,3 +114,14 @@ create-site: # ... removed for brevity ``` + +## Upgrading from images with a nested sites/assets volume + +Previous images declared `VOLUME /home/frappe/frappe-bench/sites/assets` separately. This created an implicit nested mountpoint inside the `sites` volume, which could cause Docker to attach different anonymous volumes per container in multi-container setups. +That declaration has been removed. `sites` is now the single shared mount, consistent with the compose setup and docs. + +**After pulling the updated image:** + +- Recreate all containers (`docker compose up --force-recreate`). Without this, Docker may keep the old anonymous `sites/assets` volume + attached from before the change. +- No `bench build` is needed β€” this only fixes mount consistency, not the asset workflow. From 960a3732cedc3112dc8f3c8e74e6d792145457ea Mon Sep 17 00:00:00 2001 From: ews-pgasser Date: Tue, 21 Apr 2026 09:05:34 +0200 Subject: [PATCH 218/279] chore: bump redis from 6.2 to 8.6-alpine --- overrides/compose.redis.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/overrides/compose.redis.yaml b/overrides/compose.redis.yaml index 407ad9e1..64bc05ac 100644 --- a/overrides/compose.redis.yaml +++ b/overrides/compose.redis.yaml @@ -8,11 +8,11 @@ services: - redis-queue redis-cache: - image: redis:6.2-alpine + image: redis:8.6-alpine restart: unless-stopped redis-queue: - image: redis:6.2-alpine + image: redis:8.6-alpine restart: unless-stopped volumes: - redis-queue-data:/data From 0281722f7530a3e50401187247682e7be55c6c9f Mon Sep 17 00:00:00 2001 From: RocketQuack <202538874+Rocket-Quack@users.noreply.github.com> Date: Tue, 21 Apr 2026 19:05:00 +0200 Subject: [PATCH 219/279] feat(ci): split core image workflows and publish base images to ghcr --- .github/scripts/get_latest_tags.py | 10 ++ .github/workflows/build_develop.yml | 33 ------- .../{build_bench.yml => core-build-bench.yml} | 4 +- .github/workflows/core-build-develop.yml | 49 ++++++++++ ...build_stable.yml => core-build-stable.yml} | 48 ++++++++-- ...ld-push.yml => core-build-test-images.yml} | 57 +++++++----- .github/workflows/core-publish-images.yml | 92 +++++++++++++++++++ ...publish_docs.yml => docs-publish-site.yml} | 4 +- CONTRIBUTING.md | 2 +- README.md | 4 +- docker-bake.hcl | 4 + 11 files changed, 232 insertions(+), 75 deletions(-) delete mode 100644 .github/workflows/build_develop.yml rename .github/workflows/{build_bench.yml => core-build-bench.yml} (95%) create mode 100644 .github/workflows/core-build-develop.yml rename .github/workflows/{build_stable.yml => core-build-stable.yml} (67%) rename .github/workflows/{docker-build-push.yml => core-build-test-images.yml} (64%) create mode 100644 .github/workflows/core-publish-images.yml rename .github/workflows/{publish_docs.yml => docs-publish-site.yml} (93%) diff --git a/.github/scripts/get_latest_tags.py b/.github/scripts/get_latest_tags.py index 2eb62fb7..526716ce 100644 --- a/.github/scripts/get_latest_tags.py +++ b/.github/scripts/get_latest_tags.py @@ -49,6 +49,13 @@ def update_env(file_name: str, frappe_tag: str, erpnext_tag: str | None = None): f.write(text) +def update_output(file_name: str, frappe_tag: str, erpnext_tag: str | None = None): + with open(file_name, "a", encoding="utf-8") as f: + f.write(f"frappe_version={frappe_tag}\n") + if erpnext_tag: + f.write(f"erpnext_version={erpnext_tag}\n") + + def _print_resp(frappe_tag: str, erpnext_tag: str | None = None): print(json.dumps({"frappe": frappe_tag, "erpnext": erpnext_tag})) @@ -70,6 +77,9 @@ def main(_args: list[str]) -> int: file_name = os.getenv("GITHUB_ENV") if file_name: update_env(file_name, frappe_tag, erpnext_tag) + file_name = os.getenv("GITHUB_OUTPUT") + if file_name: + update_output(file_name, frappe_tag, erpnext_tag) _print_resp(frappe_tag, erpnext_tag) return 0 diff --git a/.github/workflows/build_develop.yml b/.github/workflows/build_develop.yml deleted file mode 100644 index 8ec061ed..00000000 --- a/.github/workflows/build_develop.yml +++ /dev/null @@ -1,33 +0,0 @@ -name: Develop build - -on: - pull_request: - branches: - - main - paths: - - images/production/** - - overrides/** - - tests/** - - compose.yaml - - docker-bake.hcl - - example.env - - .github/workflows/build_develop.yml - - schedule: - # Every day at 12:00 pm - - cron: 0 0 * * * - - workflow_dispatch: - -jobs: - build: - uses: ./.github/workflows/docker-build-push.yml - with: - repo: erpnext - version: develop - push: ${{ github.repository == 'frappe/frappe_docker' && github.event_name != 'pull_request' }} - python_version: 3.14.2 - node_version: 24.12.0 - secrets: - DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }} - DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} diff --git a/.github/workflows/build_bench.yml b/.github/workflows/core-build-bench.yml similarity index 95% rename from .github/workflows/build_bench.yml rename to .github/workflows/core-build-bench.yml index 1bc47018..ef0ecbd0 100644 --- a/.github/workflows/build_bench.yml +++ b/.github/workflows/core-build-bench.yml @@ -1,4 +1,4 @@ -name: Bench +name: Core / Build Bench on: pull_request: @@ -7,7 +7,7 @@ on: paths: - images/bench/** - docker-bake.hcl - - .github/workflows/build_bench.yml + - .github/workflows/core-build-bench.yml schedule: # Every day at 12:00 pm diff --git a/.github/workflows/core-build-develop.yml b/.github/workflows/core-build-develop.yml new file mode 100644 index 00000000..64800241 --- /dev/null +++ b/.github/workflows/core-build-develop.yml @@ -0,0 +1,49 @@ +name: Core / Build Develop + +permissions: + contents: read + packages: write + +on: + pull_request: + branches: + - main + paths: + - images/production/** + - overrides/** + - tests/** + - compose.yaml + - docker-bake.hcl + - example.env + - .github/workflows/core-build-develop.yml + - .github/workflows/core-build-test-images.yml + - .github/workflows/core-publish-images.yml + + schedule: + # Every day at 12:00 pm + - cron: 0 0 * * * + + workflow_dispatch: + +jobs: + test: + uses: ./.github/workflows/core-build-test-images.yml + with: + repo: erpnext + version: develop + python_version: 3.14.2 + node_version: 24.12.0 + + publish: + if: ${{ github.repository == 'frappe/frappe_docker' && github.event_name != 'pull_request' }} + needs: test + uses: ./.github/workflows/core-publish-images.yml + with: + repo: erpnext + frappe_version: ${{ needs.test.outputs.frappe_version }} + erpnext_version: ${{ needs.test.outputs.erpnext_version }} + python_version: 3.14.2 + node_version: 24.12.0 + secrets: + DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }} + DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} diff --git a/.github/workflows/build_stable.yml b/.github/workflows/core-build-stable.yml similarity index 67% rename from .github/workflows/build_stable.yml rename to .github/workflows/core-build-stable.yml index 174516bc..6c453adb 100644 --- a/.github/workflows/build_stable.yml +++ b/.github/workflows/core-build-stable.yml @@ -1,4 +1,8 @@ -name: Stable build +name: Core / Build Stable + +permissions: + contents: read + packages: write on: pull_request: @@ -11,7 +15,9 @@ on: - compose.yaml - docker-bake.hcl - example.env - - .github/workflows/build_stable.yml + - .github/workflows/core-build-stable.yml + - .github/workflows/core-build-test-images.yml + - .github/workflows/core-publish-images.yml push: branches: @@ -23,6 +29,9 @@ on: - compose.yaml - docker-bake.hcl - example.env + - .github/workflows/core-build-stable.yml + - .github/workflows/core-build-test-images.yml + - .github/workflows/core-publish-images.yml # Triggered from frappe/frappe and frappe/erpnext on releases repository_dispatch: @@ -30,24 +39,43 @@ on: workflow_dispatch: jobs: - v15: - uses: ./.github/workflows/docker-build-push.yml + v15_test: + uses: ./.github/workflows/core-build-test-images.yml with: repo: erpnext version: "15" - push: ${{ github.repository == 'frappe/frappe_docker' && github.event_name != 'pull_request' }} + python_version: 3.11.6 + node_version: 20.19.2 + + v15_publish: + if: ${{ github.repository == 'frappe/frappe_docker' && github.event_name != 'pull_request' }} + needs: v15_test + uses: ./.github/workflows/core-publish-images.yml + with: + repo: erpnext + frappe_version: ${{ needs.v15_test.outputs.frappe_version }} + erpnext_version: ${{ needs.v15_test.outputs.erpnext_version }} python_version: 3.11.6 node_version: 20.19.2 secrets: DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }} DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} - v16: - uses: ./.github/workflows/docker-build-push.yml + v16_test: + uses: ./.github/workflows/core-build-test-images.yml with: repo: erpnext version: "16" - push: ${{ github.repository == 'frappe/frappe_docker' && github.event_name != 'pull_request' }} + python_version: 3.14.2 + node_version: 24.12.0 + v16_publish: + if: ${{ github.repository == 'frappe/frappe_docker' && github.event_name != 'pull_request' }} + needs: v16_test + uses: ./.github/workflows/core-publish-images.yml + with: + repo: erpnext + frappe_version: ${{ needs.v16_test.outputs.frappe_version }} + erpnext_version: ${{ needs.v16_test.outputs.erpnext_version }} python_version: 3.14.2 node_version: 24.12.0 secrets: @@ -58,7 +86,7 @@ jobs: name: Update example.env and pwd.yml runs-on: ubuntu-latest if: ${{ github.repository == 'frappe/frappe_docker' && github.event_name != 'pull_request' }} - needs: v16 + needs: v16_publish steps: - name: Checkout @@ -96,7 +124,7 @@ jobs: name: Release Helm runs-on: ubuntu-latest if: ${{ github.repository == 'frappe/frappe_docker' && github.event_name != 'pull_request' }} - needs: v16 + needs: v16_publish steps: - name: Setup deploy key diff --git a/.github/workflows/docker-build-push.yml b/.github/workflows/core-build-test-images.yml similarity index 64% rename from .github/workflows/docker-build-push.yml rename to .github/workflows/core-build-test-images.yml index 9fee1782..7c118c93 100644 --- a/.github/workflows/docker-build-push.yml +++ b/.github/workflows/core-build-test-images.yml @@ -1,4 +1,4 @@ -name: Build +name: Core / Build and Test Images on: workflow_call: @@ -11,9 +11,6 @@ on: required: true type: string description: "Major version, git tags should match 'v{version}.*'; or 'develop'" - push: - required: true - type: boolean python_version: required: true type: string @@ -22,16 +19,36 @@ on: required: true type: string description: NodeJS Version - secrets: - DOCKERHUB_USERNAME: - required: true - DOCKERHUB_TOKEN: - required: true + outputs: + frappe_version: + description: "Resolved frappe image tag" + value: ${{ jobs.resolve.outputs.frappe_version }} + erpnext_version: + description: "Resolved erpnext image tag" + value: ${{ jobs.resolve.outputs.erpnext_version }} + +permissions: + contents: read jobs: + resolve: + name: Resolve Versions + runs-on: ubuntu-latest + outputs: + frappe_version: ${{ steps.resolve.outputs.frappe_version }} + erpnext_version: ${{ steps.resolve.outputs.erpnext_version }} + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Resolve image versions + id: resolve + run: python3 ./.github/scripts/get_latest_tags.py --repo ${{ inputs.repo }} --version ${{ inputs.version }} + build: name: Build runs-on: ubuntu-latest + needs: resolve services: registry: image: docker.io/registry:2 @@ -57,8 +74,12 @@ jobs: driver-opts: network=host platforms: linux/${{ matrix.arch }} - - name: Get latest versions - run: python3 ./.github/scripts/get_latest_tags.py --repo ${{ inputs.repo }} --version ${{ inputs.version }} + - name: Set resolved versions + run: | + echo "FRAPPE_VERSION=${{ needs.resolve.outputs.frappe_version }}" >> "$GITHUB_ENV" + if [ -n "${{ needs.resolve.outputs.erpnext_version }}" ]; then + echo "ERPNEXT_VERSION=${{ needs.resolve.outputs.erpnext_version }}" >> "$GITHUB_ENV" + fi - name: Set build args run: | @@ -85,17 +106,3 @@ jobs: - name: Test run: venv/bin/pytest --color=yes - - - name: Login - if: ${{ inputs.push }} - uses: docker/login-action@v4 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Push - if: ${{ inputs.push }} - uses: docker/bake-action@v7.1.0 - with: - push: true - set: "*.platform=linux/amd64,linux/arm64" diff --git a/.github/workflows/core-publish-images.yml b/.github/workflows/core-publish-images.yml new file mode 100644 index 00000000..4da6bfee --- /dev/null +++ b/.github/workflows/core-publish-images.yml @@ -0,0 +1,92 @@ +name: Core / Publish Images + +on: + workflow_call: + inputs: + repo: + required: true + type: string + description: "'erpnext' or 'frappe'" + frappe_version: + required: true + type: string + description: "Resolved frappe image tag" + erpnext_version: + required: false + type: string + description: "Resolved erpnext image tag" + python_version: + required: true + type: string + description: Python Version + node_version: + required: true + type: string + description: NodeJS Version + secrets: + DOCKERHUB_USERNAME: + required: true + DOCKERHUB_TOKEN: + required: true + +permissions: + contents: read + packages: write + +jobs: + publish: + name: Publish + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Setup QEMU + uses: docker/setup-qemu-action@v4 + with: + image: tonistiigi/binfmt:latest + platforms: all + + - name: Setup Buildx + uses: docker/setup-buildx-action@v4 + + - name: Set resolved versions + run: | + echo "FRAPPE_VERSION=${{ inputs.frappe_version }}" >> "$GITHUB_ENV" + if [ -n "${{ inputs.erpnext_version }}" ]; then + echo "ERPNEXT_VERSION=${{ inputs.erpnext_version }}" >> "$GITHUB_ENV" + fi + + - name: Set build args + run: | + echo "PYTHON_VERSION=${{ inputs.python_version }}" >> "$GITHUB_ENV" + echo "NODE_VERSION=${{ inputs.node_version }}" >> "$GITHUB_ENV" + + - name: Login to Docker Hub + uses: docker/login-action@v4 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Push Docker Hub images + uses: docker/bake-action@v7.1.0 + with: + push: true + set: "*.platform=linux/amd64,linux/arm64" + + - name: Login to GHCR + uses: docker/login-action@v4 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Push GHCR base images + uses: docker/bake-action@v7.1.0 + with: + targets: base-images + push: true + set: "*.platform=linux/amd64,linux/arm64" + env: + REGISTRY_USER: ghcr.io/${{ github.repository_owner }} diff --git a/.github/workflows/publish_docs.yml b/.github/workflows/docs-publish-site.yml similarity index 93% rename from .github/workflows/publish_docs.yml rename to .github/workflows/docs-publish-site.yml index ffecb82c..32a9fb48 100644 --- a/.github/workflows/publish_docs.yml +++ b/.github/workflows/docs-publish-site.yml @@ -1,11 +1,11 @@ -name: Deploy Frappe Docker Docs to GitHub Pages +name: Docs / Publish Site on: push: branches: [main] paths: - "docs/**" - - ".github/workflows/publish_docs.yml" + - ".github/workflows/docs-publish-site.yml" workflow_dispatch: permissions: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 47be9ebb..1b1db5c4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -143,4 +143,4 @@ In case of new release of Debian. e.g. bullseye to bookworm. Change following fi Change following files on release of ERPNext -- `.github/workflows/build_stable.yml`: Add the new release step under `jobs` and remove the unmaintained one. e.g. In case v12, v13 available, v14 will be added and v12 will be removed on release of v14. Also change the `needs:` for later steps to `v14` from `v13`. +- `.github/workflows/core-build-stable.yml`: Add the new release step under `jobs` and remove the unmaintained one. e.g. In case v12, v13 available, v14 will be added and v12 will be removed on release of v14. Also change the `needs:` for later steps to `v14` from `v13`. diff --git a/README.md b/README.md index 6619e4d2..ccf213ab 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Frappe Docker -[![Build Stable](https://github.com/frappe/frappe_docker/actions/workflows/build_stable.yml/badge.svg)](https://github.com/frappe/frappe_docker/actions/workflows/build_stable.yml) -[![Build Develop](https://github.com/frappe/frappe_docker/actions/workflows/build_develop.yml/badge.svg)](https://github.com/frappe/frappe_docker/actions/workflows/build_develop.yml) +[![Build Stable](https://github.com/frappe/frappe_docker/actions/workflows/core-build-stable.yml/badge.svg)](https://github.com/frappe/frappe_docker/actions/workflows/core-build-stable.yml) +[![Build Develop](https://github.com/frappe/frappe_docker/actions/workflows/core-build-develop.yml/badge.svg)](https://github.com/frappe/frappe_docker/actions/workflows/core-build-develop.yml) Docker images and orchestration for Frappe applications. diff --git a/docker-bake.hcl b/docker-bake.hcl index baf7f3b3..cb59f835 100644 --- a/docker-bake.hcl +++ b/docker-bake.hcl @@ -62,6 +62,10 @@ group "default" { targets = ["erpnext", "base", "build"] } +group "base-images" { + targets = ["base", "build"] +} + function "tag" { params = [repo, version] result = [ From 01af0df21dd2464c554204a3a052f659d68b74d3 Mon Sep 17 00:00:00 2001 From: RocketQuack <202538874+Rocket-Quack@users.noreply.github.com> Date: Tue, 21 Apr 2026 19:05:14 +0200 Subject: [PATCH 220/279] feat(ci): add reusable workflow for downstream app images --- .github/workflows/app-build-image.yml | 189 ++++++++++++++++++++++++++ images/layered/Containerfile | 5 +- 2 files changed, 192 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/app-build-image.yml diff --git a/.github/workflows/app-build-image.yml b/.github/workflows/app-build-image.yml new file mode 100644 index 00000000..710d31c9 --- /dev/null +++ b/.github/workflows/app-build-image.yml @@ -0,0 +1,189 @@ +name: App / Build Image + +on: + workflow_call: + inputs: + app_name: + required: true + type: string + description: "App module and image name, for example 'crm'" + app_repo: + required: true + type: string + description: "Git URL or GitHub slug for the app repository" + app_ref: + required: true + type: string + description: "Git branch or tag to install for the app" + frappe_ref: + required: true + type: string + description: "Tag of the existing frappe/base and frappe/build images, for example version-16" + frappe_image_prefix: + required: false + type: string + default: frappe + description: "Image prefix for existing base and build images, for example 'frappe' or 'ghcr.io/frappe'" + image_name: + required: true + type: string + description: "Full image name, for example ghcr.io/frappe/crm" + image_tag: + required: true + type: string + description: "Image tag, for example develop or v16.0.0" + push: + required: true + type: boolean + registry: + required: false + type: string + default: docker.io + frappe_repo: + required: false + type: string + default: https://github.com/frappe/frappe + description: "Git URL for the Frappe framework repository" + builder_repository: + required: false + type: string + default: Rocket-Quack/frappe_docker + description: "Repository that contains the Containerfile and helper scripts" + builder_ref: + required: false + type: string + default: main + description: "Ref to checkout from the builder repository" + platforms: + required: false + type: string + default: linux/amd64 + description: "Docker platforms for the final build" + secrets: + REGISTRY_USERNAME: + required: false + REGISTRY_PASSWORD: + required: false + +permissions: + contents: read + packages: write + +concurrency: + group: app-image-${{ github.repository }}-${{ inputs.app_name }}-${{ inputs.app_ref }} + cancel-in-progress: true + +jobs: + build: + runs-on: ubuntu-latest + timeout-minutes: 30 + env: + BUILDER_DIR: builder + APPS_JSON_PATH: builder/.github/tmp/apps.json + CACHE_SCOPE: app-image-${{ inputs.app_name }}-${{ inputs.frappe_ref }} + TEST_IMAGE: local/${{ inputs.app_name }}:${{ github.run_id }}-${{ github.run_attempt }} + FINAL_IMAGE: ${{ inputs.image_name }}:${{ inputs.image_tag }} + + steps: + - name: Checkout builder repository + uses: actions/checkout@v6 + with: + repository: ${{ inputs.builder_repository }} + ref: ${{ inputs.builder_ref }} + path: ${{ env.BUILDER_DIR }} + + - name: Setup QEMU + uses: docker/setup-qemu-action@v4 + with: + image: tonistiigi/binfmt:latest + platforms: all + + - name: Setup Buildx + uses: docker/setup-buildx-action@v4 + + - name: Create apps.json + env: + APP_REPO: ${{ inputs.app_repo }} + APP_REF: ${{ inputs.app_ref }} + APPS_JSON_PATH: ${{ env.APPS_JSON_PATH }} + run: | + mkdir -p "$(dirname "$APPS_JSON_PATH")" + python3 - <<'PY' + import json + import os + from pathlib import Path + + repo = os.environ["APP_REPO"].strip() + ref = os.environ["APP_REF"].strip() + + if repo.count("/") == 1 and not repo.startswith(("https://", "http://")): + repo = f"https://github.com/{repo}" + + for prefix in ("refs/heads/", "refs/tags/"): + if ref.startswith(prefix): + ref = ref.removeprefix(prefix) + + Path(os.environ["APPS_JSON_PATH"]).write_text( + json.dumps([{"url": repo, "branch": ref}], indent=2) + "\n", + encoding="utf-8", + ) + PY + + - name: Build smoke-test image + uses: docker/build-push-action@v6 + with: + context: ${{ env.BUILDER_DIR }} + file: ${{ env.BUILDER_DIR }}/images/layered/Containerfile + build-args: | + FRAPPE_IMAGE_PREFIX=${{ inputs.frappe_image_prefix }} + FRAPPE_PATH=${{ inputs.frappe_repo }} + FRAPPE_BRANCH=${{ inputs.frappe_ref }} + cache-from: type=gha,scope=${{ env.CACHE_SCOPE }} + cache-to: type=gha,mode=max,scope=${{ env.CACHE_SCOPE }} + load: true + platforms: linux/amd64 + secrets: | + id=apps_json,src=${{ env.APPS_JSON_PATH }} + tags: ${{ env.TEST_IMAGE }} + + - name: Smoke test image contents + env: + APP_NAME: ${{ inputs.app_name }} + TEST_IMAGE: ${{ env.TEST_IMAGE }} + run: | + docker run --rm --entrypoint bash "$TEST_IMAGE" -lc \ + "test -d /home/frappe/frappe-bench/apps/frappe && test -d /home/frappe/frappe-bench/apps/${APP_NAME}" + + - name: Login to GHCR + if: ${{ inputs.push && inputs.registry == 'ghcr.io' }} + uses: docker/login-action@v4 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ github.token }} + + - name: Login to target registry + if: ${{ inputs.push && inputs.registry != 'ghcr.io' }} + uses: docker/login-action@v4 + with: + registry: ${{ inputs.registry }} + username: ${{ secrets.REGISTRY_USERNAME }} + password: ${{ secrets.REGISTRY_PASSWORD }} + + - name: Push multi-arch image + if: ${{ inputs.push }} + uses: docker/build-push-action@v6 + with: + context: ${{ env.BUILDER_DIR }} + file: ${{ env.BUILDER_DIR }}/images/layered/Containerfile + build-args: | + FRAPPE_IMAGE_PREFIX=${{ inputs.frappe_image_prefix }} + FRAPPE_PATH=${{ inputs.frappe_repo }} + FRAPPE_BRANCH=${{ inputs.frappe_ref }} + cache-from: type=gha,scope=${{ env.CACHE_SCOPE }} + cache-to: type=gha,mode=max,scope=${{ env.CACHE_SCOPE }} + platforms: ${{ inputs.platforms }} + push: true + secrets: | + id=apps_json,src=${{ env.APPS_JSON_PATH }} + tags: ${{ env.FINAL_IMAGE }} diff --git a/images/layered/Containerfile b/images/layered/Containerfile index 02bf9a20..808f898f 100644 --- a/images/layered/Containerfile +++ b/images/layered/Containerfile @@ -1,6 +1,7 @@ ARG FRAPPE_BRANCH=version-16 +ARG FRAPPE_IMAGE_PREFIX=frappe -FROM frappe/build:${FRAPPE_BRANCH} AS builder +FROM ${FRAPPE_IMAGE_PREFIX}/build:${FRAPPE_BRANCH} AS builder ARG FRAPPE_BRANCH=version-16 ARG FRAPPE_PATH=https://github.com/frappe/frappe @@ -24,7 +25,7 @@ RUN --mount=type=secret,id=apps_json,target=/opt/frappe/apps.json,uid=1000,gid=1 echo "{}" > sites/common_site_config.json && \ find apps -mindepth 1 -path "*/.git" | xargs rm -fr -FROM frappe/base:${FRAPPE_BRANCH} AS backend +FROM ${FRAPPE_IMAGE_PREFIX}/base:${FRAPPE_BRANCH} AS backend USER frappe From fec3af20cd75dce0da2d073e6eef5ce54ba9c532 Mon Sep 17 00:00:00 2001 From: RocketQuack <202538874+Rocket-Quack@users.noreply.github.com> Date: Tue, 21 Apr 2026 19:05:23 +0200 Subject: [PATCH 221/279] docs(ci): document current image workflow setup --- .../06-github-actions-image-workflows.md | 312 ++++++++++++++++++ 1 file changed, 312 insertions(+) create mode 100644 docs/08-reference/06-github-actions-image-workflows.md diff --git a/docs/08-reference/06-github-actions-image-workflows.md b/docs/08-reference/06-github-actions-image-workflows.md new file mode 100644 index 00000000..85805b64 --- /dev/null +++ b/docs/08-reference/06-github-actions-image-workflows.md @@ -0,0 +1,312 @@ +--- +title: GitHub Actions Image Workflows +--- + +This document describes the current workflow setup for shared core images and reusable downstream app images. + +# Workflow roles + +The current workflow layout is: + +- `.github/workflows/core-build-develop.yml` +- `.github/workflows/core-build-stable.yml` +- `.github/workflows/core-build-test-images.yml` +- `.github/workflows/core-publish-images.yml` +- `.github/workflows/app-build-image.yml` + +`core-build-develop.yml` and `core-build-stable.yml` are orchestration workflows. +They decide when the core image pipeline runs. + +`core-build-test-images.yml` is the reusable workflow that: + +- resolves the image versions for the requested release line +- builds the shared core images into a local registry +- runs the test suite against those images + +`core-publish-images.yml` is the reusable workflow that: + +- publishes the tested images to Docker Hub +- publishes `base` and `build` to GHCR + +`app-build-image.yml` is the reusable workflow that downstream repositories call to: + +- create an `apps.json` file from the caller's app repository and ref +- build `images/layered/Containerfile` +- consume existing `base` and `build` images +- install the requested app into the final image +- optionally push the final app image to the caller's registry + +# Current flow + +The current structure is: + +```text +core orchestration + -> core build and test + -> core publish + +downstream app workflow + -> consume published base and build + -> install app + -> publish final app image +``` + +Current Mermaid overview: + +```mermaid +flowchart TD + subgraph Core["Core image flow"] + A[core-build-develop.yml or core-build-stable.yml] + B[core-build-test-images.yml] + C[Resolve versions] + D[Build local test images] + E[Run pytest] + F[core-publish-images.yml] + G[Push Docker Hub: erpnext, base, build] + H[Push GHCR: base, build] + + A --> B + B --> C + C --> D + D --> E + E --> F + F --> G + F --> H + end + + subgraph App["Downstream app flow"] + I[Downstream repo workflow] + J[app-build-image.yml] + K[Create apps.json] + L[Build images/layered/Containerfile] + M[Install app] + N[Push final app image] + + I --> J + J --> K + K --> L + L --> M + M --> N + end + + G --> J + H --> J +``` + +More concretely: + +```text +core-build-test-images.yml + -> resolves frappe and erpnext tags + -> builds images into a local CI registry + -> runs tests + +core-publish-images.yml + -> pushes Docker Hub: erpnext, base, build + -> pushes GHCR: base, build + +app-build-image.yml + -> pulls: + - /base: + - /build: + -> installs app from app_repo + app_ref + -> pushes final image_name:image_tag +``` + +# Naming convention + +GitHub Actions requires workflow files to stay directly inside `.github/workflows`. +Subdirectories are not supported for workflow files, so structure should come from file names and `name:` values. + +Recommended file naming convention: + +```text +--.yml +``` + +Current examples: + +- `core-build-bench.yml` +- `core-build-develop.yml` +- `core-build-stable.yml` +- `core-build-test-images.yml` +- `core-publish-images.yml` +- `app-build-image.yml` +- `docs-publish-site.yml` + +Recommended visible workflow names: + +- `Core / Build Bench` +- `Core / Build Develop` +- `Core / Build Stable` +- `Core / Build and Test Images` +- `Core / Publish Images` +- `App / Build Image` +- `Docs / Publish Site` + +# Style rules + +To keep workflows predictable, use one convention per category instead of mixing styles. + +Workflow file names should use kebab-case: + +```text +core-build-test-images.yml +app-build-image.yml +``` + +Workflow display names should use short title-style groups: + +```text +Core / Build and Test Images +App / Build Image +``` + +Workflow inputs should use snake_case: + +```yaml +app_name: +frappe_ref: +image_name: +``` + +Environment variables should use upper snake case: + +```text +FRAPPE_IMAGE_PREFIX +PYTHON_VERSION +NODE_VERSION +``` + +The recommended rule set is: + +- workflow file names: kebab-case +- workflow `name:` values: grouped title case +- workflow inputs: snake_case +- job ids and step ids: snake_case where practical +- environment variables: UPPER_SNAKE_CASE + +This means `-` is preferred for file names, while `_` remains appropriate for YAML keys, inputs, and environment variables. + +# Important inputs in `app-build-image.yml` + +The reusable app workflow is controlled mainly by these inputs: + +- `app_name` + The application directory name, for example `crm` +- `app_repo` + The Git repository to install, for example `frappe/crm` +- `app_ref` + The branch or tag to install, for example `develop` +- `frappe_ref` + The tag of the existing `base` and `build` images, for example `version-16` +- `frappe_image_prefix` + Where the shared `base` and `build` images come from, for example `frappe` or `ghcr.io/frappe` +- `image_name` + The final target image name, for example `ghcr.io/acme/crm` +- `image_tag` + The final target image tag, for example `develop` +- `registry` + The registry for the final push, for example `ghcr.io` or `docker.io` + +The key distinction is: + +```text +frappe_image_prefix = source of shared base/build images +image_name = destination of the final app image +``` + +# Example: caller repository publishes to GHCR + +This example assumes: + +- shared base images exist in `ghcr.io/frappe/base` and `ghcr.io/frappe/build` +- the caller repository wants to publish its own app image to `ghcr.io/acme/crm` + +```yaml +name: App / Build CRM Image + +on: + workflow_dispatch: + push: + branches: + - develop + +permissions: + contents: read + packages: write + +jobs: + build-image: + uses: frappe/frappe_docker/.github/workflows/app-build-image.yml@main + with: + app_name: crm + app_repo: acme/crm + app_ref: develop + frappe_ref: version-16 + frappe_image_prefix: ghcr.io/frappe + image_name: ghcr.io/acme/crm + image_tag: develop + registry: ghcr.io + push: true + platforms: linux/amd64 +``` + +What happens: + +```text +1. app-build-image.yml is called +2. apps.json is generated from acme/crm + develop +3. the workflow builds images/layered/Containerfile +4. layered uses: + - ghcr.io/frappe/build:version-16 + - ghcr.io/frappe/base:version-16 +5. CRM is installed +6. the final image is pushed to ghcr.io/acme/crm:develop +``` + +For GHCR, the caller workflow should grant: + +- `permissions: packages: write` + +The reusable workflow then logs in with the workflow token. + +# Example: caller repository publishes to Docker Hub + +This example assumes: + +- shared base images come from Docker Hub under `frappe` +- the caller repository wants to publish its app image to Docker Hub as `acme/crm` + +```yaml +name: App / Build CRM Image + +on: + workflow_dispatch: + push: + branches: + - develop + +jobs: + build-image: + uses: frappe/frappe_docker/.github/workflows/app-build-image.yml@main + with: + app_name: crm + app_repo: acme/crm + app_ref: develop + frappe_ref: version-16 + frappe_image_prefix: frappe + image_name: acme/crm + image_tag: develop + registry: docker.io + push: true + platforms: linux/amd64 + secrets: + REGISTRY_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }} + REGISTRY_PASSWORD: ${{ secrets.DOCKERHUB_TOKEN }} +``` + +In this case: + +- shared images are pulled from `frappe/base:version-16` and `frappe/build:version-16` +- the final image is pushed to Docker Hub as `acme/crm:develop` From 3024cd132d27327b7becbb66d64510fd9a58d464 Mon Sep 17 00:00:00 2001 From: RocketQuack <202538874+Rocket-Quack@users.noreply.github.com> Date: Tue, 21 Apr 2026 19:27:39 +0200 Subject: [PATCH 222/279] chore(ci): allow image publishing on test fork --- .github/workflows/core-build-develop.yml | 2 +- .github/workflows/core-build-stable.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/core-build-develop.yml b/.github/workflows/core-build-develop.yml index 64800241..8085b553 100644 --- a/.github/workflows/core-build-develop.yml +++ b/.github/workflows/core-build-develop.yml @@ -35,7 +35,7 @@ jobs: node_version: 24.12.0 publish: - if: ${{ github.repository == 'frappe/frappe_docker' && github.event_name != 'pull_request' }} + if: ${{ contains(fromJSON('["frappe/frappe_docker","Rocket-Quack/frappe_docker"]'), github.repository) && github.event_name != 'pull_request' }} needs: test uses: ./.github/workflows/core-publish-images.yml with: diff --git a/.github/workflows/core-build-stable.yml b/.github/workflows/core-build-stable.yml index 6c453adb..5e11a015 100644 --- a/.github/workflows/core-build-stable.yml +++ b/.github/workflows/core-build-stable.yml @@ -48,7 +48,7 @@ jobs: node_version: 20.19.2 v15_publish: - if: ${{ github.repository == 'frappe/frappe_docker' && github.event_name != 'pull_request' }} + if: ${{ contains(fromJSON('["frappe/frappe_docker","Rocket-Quack/frappe_docker"]'), github.repository) && github.event_name != 'pull_request' }} needs: v15_test uses: ./.github/workflows/core-publish-images.yml with: @@ -69,7 +69,7 @@ jobs: python_version: 3.14.2 node_version: 24.12.0 v16_publish: - if: ${{ github.repository == 'frappe/frappe_docker' && github.event_name != 'pull_request' }} + if: ${{ contains(fromJSON('["frappe/frappe_docker","Rocket-Quack/frappe_docker"]'), github.repository) && github.event_name != 'pull_request' }} needs: v16_test uses: ./.github/workflows/core-publish-images.yml with: From 84a48c65eb2d7b109c7beb6c64b0f6e304a3d9ec Mon Sep 17 00:00:00 2001 From: RocketQuack <202538874+Rocket-Quack@users.noreply.github.com> Date: Tue, 21 Apr 2026 19:40:08 +0200 Subject: [PATCH 223/279] chore(ci): restore upstream defaults after fork validation --- .github/workflows/app-build-image.yml | 2 +- .github/workflows/core-build-develop.yml | 2 +- .github/workflows/core-build-stable.yml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/app-build-image.yml b/.github/workflows/app-build-image.yml index 710d31c9..74a01048 100644 --- a/.github/workflows/app-build-image.yml +++ b/.github/workflows/app-build-image.yml @@ -47,7 +47,7 @@ on: builder_repository: required: false type: string - default: Rocket-Quack/frappe_docker + default: frappe/frappe_docker description: "Repository that contains the Containerfile and helper scripts" builder_ref: required: false diff --git a/.github/workflows/core-build-develop.yml b/.github/workflows/core-build-develop.yml index 8085b553..64800241 100644 --- a/.github/workflows/core-build-develop.yml +++ b/.github/workflows/core-build-develop.yml @@ -35,7 +35,7 @@ jobs: node_version: 24.12.0 publish: - if: ${{ contains(fromJSON('["frappe/frappe_docker","Rocket-Quack/frappe_docker"]'), github.repository) && github.event_name != 'pull_request' }} + if: ${{ github.repository == 'frappe/frappe_docker' && github.event_name != 'pull_request' }} needs: test uses: ./.github/workflows/core-publish-images.yml with: diff --git a/.github/workflows/core-build-stable.yml b/.github/workflows/core-build-stable.yml index 5e11a015..6c453adb 100644 --- a/.github/workflows/core-build-stable.yml +++ b/.github/workflows/core-build-stable.yml @@ -48,7 +48,7 @@ jobs: node_version: 20.19.2 v15_publish: - if: ${{ contains(fromJSON('["frappe/frappe_docker","Rocket-Quack/frappe_docker"]'), github.repository) && github.event_name != 'pull_request' }} + if: ${{ github.repository == 'frappe/frappe_docker' && github.event_name != 'pull_request' }} needs: v15_test uses: ./.github/workflows/core-publish-images.yml with: @@ -69,7 +69,7 @@ jobs: python_version: 3.14.2 node_version: 24.12.0 v16_publish: - if: ${{ contains(fromJSON('["frappe/frappe_docker","Rocket-Quack/frappe_docker"]'), github.repository) && github.event_name != 'pull_request' }} + if: ${{ github.repository == 'frappe/frappe_docker' && github.event_name != 'pull_request' }} needs: v16_test uses: ./.github/workflows/core-publish-images.yml with: From e72767546f08cd04d142e648ff60d0c45b1a1184 Mon Sep 17 00:00:00 2001 From: simonsan <14062932+simonsan@users.noreply.github.com> Date: Tue, 21 Apr 2026 23:49:18 +0200 Subject: [PATCH 224/279] Use `mariadb-admin` for health check mysql_upgrade is not existing anymore in the new 11.x images --- pwd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pwd.yml b/pwd.yml index 4cb9b474..73f1d946 100644 --- a/pwd.yml +++ b/pwd.yml @@ -82,7 +82,7 @@ services: networks: - frappe_network healthcheck: - test: mysqladmin ping -h localhost --password=admin + test: mariadb-admin ping -h localhost --password=admin interval: 1s retries: 20 deploy: From de4c85f68f89600d4ecd9ab93c78a029a1abfe6f Mon Sep 17 00:00:00 2001 From: RocketQuack <202538874+Rocket-Quack@users.noreply.github.com> Date: Wed, 22 Apr 2026 00:07:57 +0200 Subject: [PATCH 225/279] chore(ci): add compatibility wrappers for legacy workflow names --- .github/workflows/build_develop.yml | 12 ++++++++++++ .github/workflows/build_stable.yml | 12 ++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 .github/workflows/build_develop.yml create mode 100644 .github/workflows/build_stable.yml diff --git a/.github/workflows/build_develop.yml b/.github/workflows/build_develop.yml new file mode 100644 index 00000000..dfb0ee69 --- /dev/null +++ b/.github/workflows/build_develop.yml @@ -0,0 +1,12 @@ +name: Legacy / Build Develop + +on: + workflow_dispatch: + +jobs: + delegate: + uses: ./.github/workflows/core-build-develop.yml + permissions: + contents: read + packages: write + secrets: inherit diff --git a/.github/workflows/build_stable.yml b/.github/workflows/build_stable.yml new file mode 100644 index 00000000..15438f00 --- /dev/null +++ b/.github/workflows/build_stable.yml @@ -0,0 +1,12 @@ +name: Legacy / Build Stable + +on: + workflow_dispatch: + +jobs: + delegate: + uses: ./.github/workflows/core-build-stable.yml + permissions: + contents: read + packages: write + secrets: inherit From 2fb6f2553d650c39fed4407612cdaa70baca3910 Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 22 Apr 2026 00:48:17 +0000 Subject: [PATCH 226/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 5471b7dc..7f48e72e 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/02-setup/04-env-variables.md -ERPNEXT_VERSION=v16.14.0 +ERPNEXT_VERSION=v16.15.0 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index 4cb9b474..9895ca19 100644 --- a/pwd.yml +++ b/pwd.yml @@ -1,6 +1,6 @@ services: backend: - image: frappe/erpnext:v16.14.0 + image: frappe/erpnext:v16.15.0 networks: - frappe_network deploy: @@ -16,7 +16,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v16.14.0 + image: frappe/erpnext:v16.15.0 networks: - frappe_network deploy: @@ -45,7 +45,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v16.14.0 + image: frappe/erpnext:v16.15.0 networks: - frappe_network deploy: @@ -99,7 +99,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v16.14.0 + image: frappe/erpnext:v16.15.0 networks: - frappe_network depends_on: @@ -125,7 +125,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v16.14.0 + image: frappe/erpnext:v16.15.0 networks: - frappe_network deploy: @@ -144,7 +144,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v16.14.0 + image: frappe/erpnext:v16.15.0 networks: - frappe_network deploy: @@ -181,7 +181,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v16.14.0 + image: frappe/erpnext:v16.15.0 networks: - frappe_network deploy: @@ -195,7 +195,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v16.14.0 + image: frappe/erpnext:v16.15.0 networks: - frappe_network deploy: From ef3eba6ac96d4711f21421407427b1b8a07f6897 Mon Sep 17 00:00:00 2001 From: Thomas Date: Wed, 22 Apr 2026 11:44:03 +0200 Subject: [PATCH 227/279] enable pnpm via corepack in prod containerfil --- images/production/Containerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/images/production/Containerfile b/images/production/Containerfile index abebba86..47703d66 100644 --- a/images/production/Containerfile +++ b/images/production/Containerfile @@ -43,6 +43,7 @@ RUN useradd -ms /bin/bash frappe \ && nvm install ${NODE_VERSION} \ && nvm use v${NODE_VERSION} \ && npm install -g yarn \ + && corepack enable pnpm \ && nvm alias default v${NODE_VERSION} \ && rm -rf ${NVM_DIR}/.cache \ && echo 'export NVM_DIR="/home/frappe/.nvm"' >>/home/frappe/.bashrc \ From bcdd8127c0de77e442d4f2ebaed775e81130608f Mon Sep 17 00:00:00 2001 From: RocketQuack <202538874+Rocket-Quack@users.noreply.github.com> Date: Wed, 22 Apr 2026 15:18:35 +0200 Subject: [PATCH 228/279] docs(readme): clarify demo setup and remove play-with-docker link because no longer available --- README.md | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index ccf213ab..f6868ee2 100644 --- a/README.md +++ b/README.md @@ -50,17 +50,13 @@ If you are already familiar with Frappe, you can jump right into the [different ## Demo setup -The fastest way to try Frappe is to play in an already set up sandbox, in your browser, click the button below: - - - Try in PWD - +The fastest way to try Frappe locally is with the single-file demo setup in `pwd.yml`. ### Try on your environment > **⚠️ Disposable demo only** > -> **This setup is intended for quick evaluation. Expect to throw the environment away.** You will not be able to install custom apps to this setup. For production deployments, custom configurations, and detailed explanations, see the full documentation. +> **This setup is intended for short-lived evaluation only.** You will not be able to install custom apps to this setup. For production deployments, custom configurations, and detailed explanations, see the full documentation. First clone the repo: From 9a345364e42d4f4f7c8875cca1cb89e075f6c6ba Mon Sep 17 00:00:00 2001 From: RocketQuack <202538874+Rocket-Quack@users.noreply.github.com> Date: Wed, 22 Apr 2026 15:19:19 +0200 Subject: [PATCH 229/279] docs(readme): remove duplicate documentation links --- README.md | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/README.md b/README.md index f6868ee2..cc333e4a 100644 --- a/README.md +++ b/README.md @@ -73,22 +73,6 @@ docker compose -f pwd.yml up -d Wait for a couple of minutes for ERPNext site to be created or check `create-site` container logs before opening browser on port `8080`. (username: `Administrator`, password: `admin`) -## Documentation Links - -### [Getting Started Guide](docs/getting-started.md) - -### [Frequently Asked Questions](https://github.com/frappe/frappe_docker/wiki/Frequently-Asked-Questions) - -### [Getting Started](#getting-started) - -### [Deployment Methods](docs/01-getting-started/01-choosing-a-deployment-method.md) - -### [ARM64](docs/01-getting-started/03-arm64.md) - -### [Container Setup Overview](docs/02-setup/01-overview.md) - -### [Development](docs/05-development/01-development.md) - ## Contributing Contributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines. From 68a8ed8a8472f9b293e5b7965f707f012259afca Mon Sep 17 00:00:00 2001 From: RocketQuack <202538874+Rocket-Quack@users.noreply.github.com> Date: Wed, 22 Apr 2026 15:16:20 +0200 Subject: [PATCH 230/279] docs(readme): refresh README header and overview --- README.md | 49 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 38 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index cc333e4a..769efef7 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,37 @@ -# Frappe Docker - -[![Build Stable](https://github.com/frappe/frappe_docker/actions/workflows/core-build-stable.yml/badge.svg)](https://github.com/frappe/frappe_docker/actions/workflows/core-build-stable.yml) -[![Build Develop](https://github.com/frappe/frappe_docker/actions/workflows/core-build-develop.yml/badge.svg)](https://github.com/frappe/frappe_docker/actions/workflows/core-build-develop.yml) - -Docker images and orchestration for Frappe applications. +
+ Frappe Docker +

Frappe Docker

+

Docker images and orchestration for Frappe applications.

+

+ + Build Stable + + + Build Develop + + + Docs + +

+
## What is this? -This repository handles the containerization of the Frappe stack, including the application server, database, Redis, and supporting services. It provides quick disposable demo setups, a development environment, production-ready Docker images and compose configurations for deploying Frappe applications including ERPNext. +This repository is the official container setup for Frappe applications. + +It provides Docker images, Compose configurations, and documentation for running Frappe applications, including ERPNext, CRM, Helpdesk, and other Frappe apps, in containers. + +Use it if you want to: + +- run ERPNext, CRM, Helpdesk, or other Frappe apps with Docker +- start from a quick demo setup +- use production-ready Docker images and Compose setups +- build custom app images +- deploy and operate Frappe in production ## Repository Structure -``` +```bash frappe_docker/ β”œβ”€β”€ docs/ # Complete documentation β”œβ”€β”€ overrides/ # Docker Compose configurations for different scenarios @@ -34,11 +54,18 @@ frappe_docker/ ## Documentation -**The official documentation for `frappe_docker` is maintained in the `docs/` folder in this repository.** +The full `frappe_docker` documentation is available in [`docs/`](docs/) and published at [frappe.github.io/frappe_docker](https://frappe.github.io/frappe_docker/). -**New to Frappe Docker?** Read the [Getting Started Guide](docs/getting-started.md) for a comprehensive overview of repository structure, development workflow, custom apps, Docker concepts, and quick start examples. +### Recommended entry points: -If you are already familiar with Frappe, you can jump right into the [different deployment methods](docs/01-getting-started/01-choosing-a-deployment-method.md) and select the one best suited to your use case. +- **New here:** [Getting Started Guide](docs/getting-started.md) +- **Choosing a setup:** [Deployment methods](docs/01-getting-started/01-choosing-a-deployment-method.md) +- **ARM64 notes:** [ARM64](docs/01-getting-started/03-arm64.md) +- **Container setup overview:** [Container Setup Overview](docs/02-setup/01-overview.md) +- **Running in production:** [Production docs](docs/03-production/) +- **Operating a deployment:** [Operations docs](docs/04-operations/) +- **Development workflows:** [Development](docs/05-development/01-development.md) +- **FAQ:** [Frequently Asked Questions](https://github.com/frappe/frappe_docker/wiki/Frequently-Asked-Questions) ## Prerequisites From 05dfe8912f5cf8882ab968107959368ebfdcf9bc Mon Sep 17 00:00:00 2001 From: Daniel Radl Date: Wed, 22 Apr 2026 16:31:19 +0200 Subject: [PATCH 231/279] fix(pwd): use mariadb healthcheck.sh --- pwd.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pwd.yml b/pwd.yml index 73f1d946..dd5751d6 100644 --- a/pwd.yml +++ b/pwd.yml @@ -82,9 +82,11 @@ services: networks: - frappe_network healthcheck: - test: mariadb-admin ping -h localhost --password=admin - interval: 1s - retries: 20 + test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"] + start_period: 5s + interval: 5s + timeout: 5s + retries: 5 deploy: restart_policy: condition: on-failure From dabfb427775fe2154ab7ff9f1f70a271e6f74b4f Mon Sep 17 00:00:00 2001 From: Daniel Radl Date: Wed, 22 Apr 2026 16:38:55 +0200 Subject: [PATCH 232/279] fix(docs): add title to 06.03 --- docs/06-migration/03-postgres-major-version-upgrade.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/06-migration/03-postgres-major-version-upgrade.md b/docs/06-migration/03-postgres-major-version-upgrade.md index b20b94bb..1dfde6c7 100644 --- a/docs/06-migration/03-postgres-major-version-upgrade.md +++ b/docs/06-migration/03-postgres-major-version-upgrade.md @@ -1,3 +1,7 @@ +--- +title: Postgres Major Version Upgrade +--- + # PostgreSQL Major Version Upgrade (v13 to v15) Upgrading PostgreSQL from version 13 to 15 is a major version jump. Since PostgreSQL does not support in-place data directory upgrades, existing users must manually migrate their data using `pg_dump`. From a41764b9cc72d6c65ad21531d3d561975f52f05b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 23 Apr 2026 08:23:59 +0000 Subject: [PATCH 233/279] chore(deps): bump docker/build-push-action from 6 to 7 Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6 to 7. - [Release notes](https://github.com/docker/build-push-action/releases) - [Commits](https://github.com/docker/build-push-action/compare/v6...v7) --- updated-dependencies: - dependency-name: docker/build-push-action dependency-version: '7' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/app-build-image.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/app-build-image.yml b/.github/workflows/app-build-image.yml index 74a01048..df63d19a 100644 --- a/.github/workflows/app-build-image.yml +++ b/.github/workflows/app-build-image.yml @@ -130,7 +130,7 @@ jobs: PY - name: Build smoke-test image - uses: docker/build-push-action@v6 + uses: docker/build-push-action@v7 with: context: ${{ env.BUILDER_DIR }} file: ${{ env.BUILDER_DIR }}/images/layered/Containerfile @@ -172,7 +172,7 @@ jobs: - name: Push multi-arch image if: ${{ inputs.push }} - uses: docker/build-push-action@v6 + uses: docker/build-push-action@v7 with: context: ${{ env.BUILDER_DIR }} file: ${{ env.BUILDER_DIR }}/images/layered/Containerfile From 6633e61bfb9910c1a04479df6fadce422e79c07e Mon Sep 17 00:00:00 2001 From: RocketQuack <202538874+Rocket-Quack@users.noreply.github.com> Date: Fri, 24 Apr 2026 16:08:26 +0200 Subject: [PATCH 234/279] fix(workflows): enable reusable core build workflows --- .github/workflows/core-build-develop.yml | 2 ++ .github/workflows/core-build-stable.yml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/.github/workflows/core-build-develop.yml b/.github/workflows/core-build-develop.yml index 64800241..8e6ceefe 100644 --- a/.github/workflows/core-build-develop.yml +++ b/.github/workflows/core-build-develop.yml @@ -5,6 +5,8 @@ permissions: packages: write on: + workflow_call: + pull_request: branches: - main diff --git a/.github/workflows/core-build-stable.yml b/.github/workflows/core-build-stable.yml index 6c453adb..e6cdb951 100644 --- a/.github/workflows/core-build-stable.yml +++ b/.github/workflows/core-build-stable.yml @@ -5,6 +5,8 @@ permissions: packages: write on: + workflow_call: + pull_request: branches: - main From d2308438d0799bc7527d0cf8a342ba1f1d94ae83 Mon Sep 17 00:00:00 2001 From: jslocomotor <210083531+jslocomotor@users.noreply.github.com> Date: Fri, 24 Apr 2026 17:11:06 +0200 Subject: [PATCH 235/279] fix(build): add apps.json hash for cache invalidation --- docs/02-setup/02-build-setup.md | 78 +++++++++++++++++++++------------ images/custom/Containerfile | 2 + images/layered/Containerfile | 2 + 3 files changed, 55 insertions(+), 27 deletions(-) diff --git a/docs/02-setup/02-build-setup.md b/docs/02-setup/02-build-setup.md index d0e6907b..9d14e596 100644 --- a/docs/02-setup/02-build-setup.md +++ b/docs/02-setup/02-build-setup.md @@ -7,7 +7,7 @@ This guide walks you through building Frappe images from the repository resource # Prerequisites - git -- docker (Engine **v23.0+**) or podman +- docker (Engine **v23.0+** with buildx) or podman - docker compose v2 or podman compose > Install containerization software according to the official maintainer documentation. Avoid package managers when not recommended, as they frequently cause compatibility issues. @@ -23,7 +23,7 @@ cd frappe_docker # Define custom apps -If you dont want to install specific apps to the image skip this section. +If you don't want to include custom apps in the image, skip this section. To include custom apps in your image, create an `apps.json` file in the repository root: @@ -31,11 +31,11 @@ To include custom apps in your image, create an `apps.json` file in the reposito [ { "url": "https://github.com/frappe/erpnext", - "branch": "version-15" + "branch": "version-16" }, { "url": "https://github.com/frappe/hrms", - "branch": "version-15" + "branch": "version-16" }, { "url": "https://github.com/frappe/helpdesk", @@ -44,7 +44,9 @@ To include custom apps in your image, create an `apps.json` file in the reposito ] ``` -# Build the image +# Build custom images + +## Manually Choose the appropriate build command based on your container runtime and desired image type. This example builds the `layered` image with the custom `apps.json` you created. @@ -55,9 +57,10 @@ Choose the appropriate build command based on your container runtime and desired ```bash docker build \ --build-arg=FRAPPE_PATH=https://github.com/frappe/frappe \ - --build-arg=FRAPPE_BRANCH=version-15 \ + --build-arg=FRAPPE_BRANCH=version-16 \ + --build-arg=APPS_JSON_HASH="$(sha256sum apps.json | awk '{print $1}')" \ --secret=id=apps_json,src=apps.json \ - --tag=custom:15 \ + --tag=custom:16 \ --file=images/layered/Containerfile . ``` @@ -66,30 +69,51 @@ docker build \ ```bash podman build \ --build-arg=FRAPPE_PATH=https://github.com/frappe/frappe \ - --build-arg=FRAPPE_BRANCH=version-15 \ + --build-arg=FRAPPE_BRANCH=version-16 \ + --build-arg=APPS_JSON_HASH="$(sha256sum apps.json | awk '{print $1}')" \ --secret=id=apps_json,src=apps.json \ - --tag=custom:15 \ + --tag=custom:16 \ --file=images/layered/Containerfile . ``` -## Build args +## CI/CD pipelines -| Arg | Purpose | -| -------------------- | ----------------------------------------------------------------------------------------------- | -| **Frappe Framework** | | -| FRAPPE_PATH | Repository URL for Frappe framework source code. Defaults to | -| FRAPPE_BRANCH | Branch to use for Frappe framework. Defaults to version-15 | -| **Custom Apps** | | -| (secret) apps_json | Passed via `--secret=id=apps_json,src=apps.json`. Never use `--build-arg` for this file. | -| **Dependencies** | | -| PYTHON_VERSION | Python version for the base image | -| NODE_VERSION | Node.js version | -| WKHTMLTOPDF_VERSION | wkhtmltopdf version | -| **bench only** | | -| DEBIAN_BASE | Debian base version for the bench image, defaults to `bookworm` | -| WKHTMLTOPDF_DISTRO | use the specified distro for debian package. Default is `bookworm` | +Example: -# env file +```yaml +- name: Build Docker image + shell: sh + run: | + docker build \ + --build-arg=FRAPPE_PATH=https://github.com/frappe/frappe \ + --build-arg=FRAPPE_BRANCH=version-16 \ + --build-arg=APPS_JSON_HASH="$(sha256sum apps.json | awk '{print $1}')" \ + --secret=id=apps_json,src=apps.json \ + --tag=custom:16 \ + --file=images/layered/Containerfile . +``` + +## Build args, secrets and flags + +| Variable | Purpose | +| -------------------- | ------------------------------------------------------------------------------------------------ | +| **Frappe Framework** | | +| FRAPPE_PATH | Repository URL for Frappe framework source code. Defaults to | +| FRAPPE_BRANCH | Branch to use for Frappe framework. Defaults to version-16 | +| **Custom Apps** | | +| APPS_JSON_HASH | Hash of `apps.json`, used to invalidate the cached layer when `apps_json` is passed as a secret. | +| (secret) apps_json | Passed via `--secret=id=apps_json,src=apps.json`. Never use `--build-arg` for this file. | +| **Dependencies** | | +| PYTHON_VERSION | Python version for the base image | +| NODE_VERSION | Node.js version | +| WKHTMLTOPDF_VERSION | wkhtmltopdf version | +| **bench only** | | +| DEBIAN_BASE | Debian base version for the bench image, defaults to `bookworm` | +| WKHTMLTOPDF_DISTRO | use the specified distro for debian package. Default is `bookworm` | + +# Deploy the stack + +## env file The compose file requires several environment variables. You can either export them on your system or create a `.env` file. @@ -103,7 +127,7 @@ For this setup, make sure **at least** the following values are added to `custom ```txt CUSTOM_IMAGE=custom -CUSTOM_TAG=15 +CUSTOM_TAG=16 PULL_POLICY=missing ``` @@ -113,7 +137,7 @@ PULL_POLICY=missing **⚠️ This is not meant to be a complete `.env` configuration guide. These are only the minimal additions required for this example. Please have a look at [env-variables.md](04-env-variables.md) for a full description of all available variables and adjust them according to your needs.** -# Creating the final compose file +## Creating the final compose file Combine the base compose file with appropriate overrides for your use case. This example adds MariaDB, Redis, and exposes ports on `:8080`: diff --git a/images/custom/Containerfile b/images/custom/Containerfile index febc72b9..298f0381 100644 --- a/images/custom/Containerfile +++ b/images/custom/Containerfile @@ -118,7 +118,9 @@ USER frappe ARG FRAPPE_BRANCH=version-16 ARG FRAPPE_PATH=https://github.com/frappe/frappe +ARG APPS_JSON_HASH="" RUN --mount=type=secret,id=apps_json,target=/opt/frappe/apps.json,uid=1000,gid=1000 \ + : "${APPS_JSON_HASH}" && \ export APP_INSTALL_ARGS="" && \ if [ -f /opt/frappe/apps.json ] && [ -s /opt/frappe/apps.json ]; then \ export APP_INSTALL_ARGS="--apps_path=/opt/frappe/apps.json"; \ diff --git a/images/layered/Containerfile b/images/layered/Containerfile index 808f898f..fd1398a5 100644 --- a/images/layered/Containerfile +++ b/images/layered/Containerfile @@ -5,10 +5,12 @@ FROM ${FRAPPE_IMAGE_PREFIX}/build:${FRAPPE_BRANCH} AS builder ARG FRAPPE_BRANCH=version-16 ARG FRAPPE_PATH=https://github.com/frappe/frappe +ARG APPS_JSON_HASH="" USER frappe RUN --mount=type=secret,id=apps_json,target=/opt/frappe/apps.json,uid=1000,gid=1000 \ + : "${APPS_JSON_HASH}" && \ export APP_INSTALL_ARGS="" && \ if [ -f /opt/frappe/apps.json ] && [ -s /opt/frappe/apps.json ]; then \ export APP_INSTALL_ARGS="--apps_path=/opt/frappe/apps.json"; \ From 71399ec0f37b60866ae285ad2c96740a62a19f1c Mon Sep 17 00:00:00 2001 From: RocketQuack <202538874+Rocket-Quack@users.noreply.github.com> Date: Fri, 24 Apr 2026 17:29:39 +0200 Subject: [PATCH 236/279] fix(workflows): allow stable env update push --- .github/workflows/build_stable.yml | 2 +- .github/workflows/core-build-stable.yml | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build_stable.yml b/.github/workflows/build_stable.yml index 15438f00..c00f89f6 100644 --- a/.github/workflows/build_stable.yml +++ b/.github/workflows/build_stable.yml @@ -7,6 +7,6 @@ jobs: delegate: uses: ./.github/workflows/core-build-stable.yml permissions: - contents: read + contents: write packages: write secrets: inherit diff --git a/.github/workflows/core-build-stable.yml b/.github/workflows/core-build-stable.yml index e6cdb951..e5fe663b 100644 --- a/.github/workflows/core-build-stable.yml +++ b/.github/workflows/core-build-stable.yml @@ -89,6 +89,8 @@ jobs: runs-on: ubuntu-latest if: ${{ github.repository == 'frappe/frappe_docker' && github.event_name != 'pull_request' }} needs: v16_publish + permissions: + contents: write steps: - name: Checkout From 007ae42d2f01c5e49d90d08c554fa645ddf3bd0a Mon Sep 17 00:00:00 2001 From: github-actions Date: Fri, 24 Apr 2026 16:24:36 +0000 Subject: [PATCH 237/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 7f48e72e..63ede817 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/02-setup/04-env-variables.md -ERPNEXT_VERSION=v16.15.0 +ERPNEXT_VERSION=v16.15.1 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index adb3601d..0633f1ef 100644 --- a/pwd.yml +++ b/pwd.yml @@ -1,6 +1,6 @@ services: backend: - image: frappe/erpnext:v16.15.0 + image: frappe/erpnext:v16.15.1 networks: - frappe_network deploy: @@ -16,7 +16,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v16.15.0 + image: frappe/erpnext:v16.15.1 networks: - frappe_network deploy: @@ -45,7 +45,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v16.15.0 + image: frappe/erpnext:v16.15.1 networks: - frappe_network deploy: @@ -101,7 +101,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v16.15.0 + image: frappe/erpnext:v16.15.1 networks: - frappe_network depends_on: @@ -127,7 +127,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v16.15.0 + image: frappe/erpnext:v16.15.1 networks: - frappe_network deploy: @@ -146,7 +146,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v16.15.0 + image: frappe/erpnext:v16.15.1 networks: - frappe_network deploy: @@ -183,7 +183,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v16.15.0 + image: frappe/erpnext:v16.15.1 networks: - frappe_network deploy: @@ -197,7 +197,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v16.15.0 + image: frappe/erpnext:v16.15.1 networks: - frappe_network deploy: From a260d9a4314dcfa043d0dbfffbd9eded0f266746 Mon Sep 17 00:00:00 2001 From: jslocomotor <210083531+jslocomotor@users.noreply.github.com> Date: Sat, 25 Apr 2026 17:06:20 +0200 Subject: [PATCH 238/279] fix(build): add optional CACHE_BUST for custom image rebuilds --- docs/02-setup/02-build-setup.md | 74 ++++++++++++++++++++++----------- images/custom/Containerfile | 5 ++- images/layered/Containerfile | 4 +- 3 files changed, 55 insertions(+), 28 deletions(-) diff --git a/docs/02-setup/02-build-setup.md b/docs/02-setup/02-build-setup.md index 9d14e596..34a1b16d 100644 --- a/docs/02-setup/02-build-setup.md +++ b/docs/02-setup/02-build-setup.md @@ -56,9 +56,9 @@ Choose the appropriate build command based on your container runtime and desired ```bash docker build \ + --no-cache \ --build-arg=FRAPPE_PATH=https://github.com/frappe/frappe \ --build-arg=FRAPPE_BRANCH=version-16 \ - --build-arg=APPS_JSON_HASH="$(sha256sum apps.json | awk '{print $1}')" \ --secret=id=apps_json,src=apps.json \ --tag=custom:16 \ --file=images/layered/Containerfile . @@ -68,9 +68,9 @@ docker build \ ```bash podman build \ + --no-cache \ --build-arg=FRAPPE_PATH=https://github.com/frappe/frappe \ --build-arg=FRAPPE_BRANCH=version-16 \ - --build-arg=APPS_JSON_HASH="$(sha256sum apps.json | awk '{print $1}')" \ --secret=id=apps_json,src=apps.json \ --tag=custom:16 \ --file=images/layered/Containerfile . @@ -78,38 +78,64 @@ podman build \ ## CI/CD pipelines -Example: +When using automated builds, `CACHE_BUST` can be used to control cache invalidation of the frappe layer in order to rebuild it. + +Possible techniques: + +- No override: normal Docker layer caching is used +- Timestamp: force a rebuild on every pipeline run +- Pipeline run ID: rebuild once per CI run +- Commit SHA: rebuild once per commit +- apps.json hash: rebuild only when the custom app definition changes + +Examples: +Commit SHA from GitHub ```yaml - name: Build Docker image shell: sh run: | docker build \ - --build-arg=FRAPPE_PATH=https://github.com/frappe/frappe \ - --build-arg=FRAPPE_BRANCH=version-16 \ - --build-arg=APPS_JSON_HASH="$(sha256sum apps.json | awk '{print $1}')" \ - --secret=id=apps_json,src=apps.json \ - --tag=custom:16 \ - --file=images/layered/Containerfile . + --build-arg=FRAPPE_PATH=https://github.com/frappe/frappe \ + --build-arg=FRAPPE_BRANCH=version-16 \ + --build-arg=CACHE_BUST="$GITHUB_SHA" \ + --secret=id=apps_json,src=apps.json \ + --tag=custom:16 \ + --file=images/layered/Containerfile . +``` + +apps.json hash + +```yaml +- name: Build Docker image + shell: sh + run: | + docker build \ + --build-arg=FRAPPE_PATH=https://github.com/frappe/frappe \ + --build-arg=FRAPPE_BRANCH=version-16 \ + --build-arg=CACHE_BUST="$(sha256sum apps.json | awk '{print $1}')" \ + --secret=id=apps_json,src=apps.json \ + --tag=custom:16 \ + --file=images/layered/Containerfile . ``` ## Build args, secrets and flags -| Variable | Purpose | -| -------------------- | ------------------------------------------------------------------------------------------------ | -| **Frappe Framework** | | -| FRAPPE_PATH | Repository URL for Frappe framework source code. Defaults to | -| FRAPPE_BRANCH | Branch to use for Frappe framework. Defaults to version-16 | -| **Custom Apps** | | -| APPS_JSON_HASH | Hash of `apps.json`, used to invalidate the cached layer when `apps_json` is passed as a secret. | -| (secret) apps_json | Passed via `--secret=id=apps_json,src=apps.json`. Never use `--build-arg` for this file. | -| **Dependencies** | | -| PYTHON_VERSION | Python version for the base image | -| NODE_VERSION | Node.js version | -| WKHTMLTOPDF_VERSION | wkhtmltopdf version | -| **bench only** | | -| DEBIAN_BASE | Debian base version for the bench image, defaults to `bookworm` | -| WKHTMLTOPDF_DISTRO | use the specified distro for debian package. Default is `bookworm` | +| Variable | Purpose | +| -------------------- | ----------------------------------------------------------------------------------------------- | +| **Frappe Framework** | | +| FRAPPE_PATH | Repository URL for Frappe framework source code. Defaults to | +| FRAPPE_BRANCH | Branch to use for Frappe framework. Defaults to version-16 | +| **Custom Apps** | | +| CACHE_BUST | Can be used to invalidate the cached layer when `apps_json` is passed as a secret. | +| (secret) apps_json | Passed via `--secret=id=apps_json,src=apps.json`. Never use `--build-arg` for this file. | +| **Dependencies** | | +| PYTHON_VERSION | Python version for the base image | +| NODE_VERSION | Node.js version | +| WKHTMLTOPDF_VERSION | wkhtmltopdf version | +| **bench only** | | +| DEBIAN_BASE | Debian base version for the bench image, defaults to `bookworm` | +| WKHTMLTOPDF_DISTRO | use the specified distro for debian package. Default is `bookworm` | # Deploy the stack diff --git a/images/custom/Containerfile b/images/custom/Containerfile index 298f0381..c99ff880 100644 --- a/images/custom/Containerfile +++ b/images/custom/Containerfile @@ -118,9 +118,10 @@ USER frappe ARG FRAPPE_BRANCH=version-16 ARG FRAPPE_PATH=https://github.com/frappe/frappe -ARG APPS_JSON_HASH="" +ARG CACHE_BUST="" + RUN --mount=type=secret,id=apps_json,target=/opt/frappe/apps.json,uid=1000,gid=1000 \ - : "${APPS_JSON_HASH}" && \ + : "${CACHE_BUST}" && \ export APP_INSTALL_ARGS="" && \ if [ -f /opt/frappe/apps.json ] && [ -s /opt/frappe/apps.json ]; then \ export APP_INSTALL_ARGS="--apps_path=/opt/frappe/apps.json"; \ diff --git a/images/layered/Containerfile b/images/layered/Containerfile index fd1398a5..0048930f 100644 --- a/images/layered/Containerfile +++ b/images/layered/Containerfile @@ -5,12 +5,12 @@ FROM ${FRAPPE_IMAGE_PREFIX}/build:${FRAPPE_BRANCH} AS builder ARG FRAPPE_BRANCH=version-16 ARG FRAPPE_PATH=https://github.com/frappe/frappe -ARG APPS_JSON_HASH="" +ARG CACHE_BUST="" USER frappe RUN --mount=type=secret,id=apps_json,target=/opt/frappe/apps.json,uid=1000,gid=1000 \ - : "${APPS_JSON_HASH}" && \ + : "${CACHE_BUST}" && \ export APP_INSTALL_ARGS="" && \ if [ -f /opt/frappe/apps.json ] && [ -s /opt/frappe/apps.json ]; then \ export APP_INSTALL_ARGS="--apps_path=/opt/frappe/apps.json"; \ From 8428dfe9ba39e8ae96c5a683e2db678c8a82f3a8 Mon Sep 17 00:00:00 2001 From: jslocomotor <210083531+jslocomotor@users.noreply.github.com> Date: Mon, 27 Apr 2026 21:37:16 +0200 Subject: [PATCH 239/279] docs(production): add automated builds and deployment guide --- docs/02-setup/02-build-setup.md | 43 +----- .../06-automated-builds-and-deployment.md | 128 ++++++++++++++++++ 2 files changed, 131 insertions(+), 40 deletions(-) create mode 100644 docs/03-production/06-automated-builds-and-deployment.md diff --git a/docs/02-setup/02-build-setup.md b/docs/02-setup/02-build-setup.md index 34a1b16d..0bf47810 100644 --- a/docs/02-setup/02-build-setup.md +++ b/docs/02-setup/02-build-setup.md @@ -76,48 +76,11 @@ podman build \ --file=images/layered/Containerfile . ``` -## CI/CD pipelines +## Automated -When using automated builds, `CACHE_BUST` can be used to control cache invalidation of the frappe layer in order to rebuild it. +This repository is fully suited for automated builds, i.e. using CI/CD pipelines. -Possible techniques: - -- No override: normal Docker layer caching is used -- Timestamp: force a rebuild on every pipeline run -- Pipeline run ID: rebuild once per CI run -- Commit SHA: rebuild once per commit -- apps.json hash: rebuild only when the custom app definition changes - -Examples: -Commit SHA from GitHub - -```yaml -- name: Build Docker image - shell: sh - run: | - docker build \ - --build-arg=FRAPPE_PATH=https://github.com/frappe/frappe \ - --build-arg=FRAPPE_BRANCH=version-16 \ - --build-arg=CACHE_BUST="$GITHUB_SHA" \ - --secret=id=apps_json,src=apps.json \ - --tag=custom:16 \ - --file=images/layered/Containerfile . -``` - -apps.json hash - -```yaml -- name: Build Docker image - shell: sh - run: | - docker build \ - --build-arg=FRAPPE_PATH=https://github.com/frappe/frappe \ - --build-arg=FRAPPE_BRANCH=version-16 \ - --build-arg=CACHE_BUST="$(sha256sum apps.json | awk '{print $1}')" \ - --secret=id=apps_json,src=apps.json \ - --tag=custom:16 \ - --file=images/layered/Containerfile . -``` +See [Automated Builds and Deployment](../03-production/06-automated-builds-and-deployment.md) for more information. ## Build args, secrets and flags diff --git a/docs/03-production/06-automated-builds-and-deployment.md b/docs/03-production/06-automated-builds-and-deployment.md new file mode 100644 index 00000000..85113f51 --- /dev/null +++ b/docs/03-production/06-automated-builds-and-deployment.md @@ -0,0 +1,128 @@ +--- +title: Automated Builds and Deployment +--- + +# Introduction + +This is a brief guide to automated builds and deployment for custom Frappe images. +Depending on your specific setup, environment and security rules, the information below may need to be adapted to your needs. + +# Requirements + +## Knowledge + +Basic knowledge of Docker and build pipelines is expected. + +Please refer to the Setup chapter first, especially [Build Setup](../02-setup/02-build-setup.md), for basic understanding. + +## Additional Files + +### Apps + +At build time an `apps.json` file can be provided. This specifies additional Frappe framework compatible apps to include in custom images. + +### Build + +A workflow file for your CI platform and environment is required. + +## Build Cache + +Unlike manual builds, automated build commands should generally not use `--no-cache`. + +Reusing cached layers can greatly reduce build times, disk usage, and bandwidth usage when pushing to image registries. + +Instead, `CACHE_BUST` can be used to control cache invalidation of the Frappe layer when rebuilding is desired. + +This is especially relevant because `apps.json` is provided as a secret. Secret contents are not part of Docker layer cache keys and therefore cannot trigger cache invalidation automatically. + +As a result, Docker may reuse an older cached layer even when the custom app definition has changed. + +Exception: Newer releases of the Frappe framework may still trigger rebuilding the layer. + +### Possible techniques for cache invalidation using `CACHE_BUST`: + +1. No override: normal Docker layer caching is used - not recommended in this use case +2. Timestamp: force a rebuild on every pipeline run - since the value will change every run +3. Pipeline run ID: rebuild once per CI run +4. Commit SHA: rebuild once per commit +5. apps.json hash: rebuild only when the custom app definition changes - additional requirements, see below example + +### Examples: + +#### 1. No override - not recommended + +This will reuse a previously build layer and won't check for app updates except Frappe framework + +```yaml +- name: Build Docker image + shell: sh + run: | + docker build \ + --build-arg=FRAPPE_PATH=https://github.com/frappe/frappe \ + --build-arg=FRAPPE_BRANCH=version-16 \ + --secret=id=apps_json,src=apps.json \ + --tag=custom:16 \ + --file=images/layered/Containerfile . +``` + +#### 2. Timestamp + +```yaml +- name: Build Docker image + shell: sh + run: | + docker build \ + --build-arg=FRAPPE_PATH=https://github.com/frappe/frappe \ + --build-arg=FRAPPE_BRANCH=version-16 \ + --build-arg=CACHE_BUST="$(date +%s)" \ + --secret=id=apps_json,src=apps.json \ + --tag=custom:16 \ + --file=images/layered/Containerfile . +``` + +#### 3. Pipeline run ID from GitHub + +```yaml +- name: Build Docker image + shell: sh + run: | + docker build \ + --build-arg=FRAPPE_PATH=https://github.com/frappe/frappe \ + --build-arg=FRAPPE_BRANCH=version-16 \ + --build-arg=CACHE_BUST="$GITHUB_RUN_ID" \ + --secret=id=apps_json,src=apps.json \ + --tag=custom:16 \ + --file=images/layered/Containerfile . +``` + +#### 4. Commit SHA from GitHub + +```yaml +- name: Build Docker image + shell: sh + run: | + docker build \ + --build-arg=FRAPPE_PATH=https://github.com/frappe/frappe \ + --build-arg=FRAPPE_BRANCH=version-16 \ + --build-arg=CACHE_BUST="$GITHUB_SHA" \ + --secret=id=apps_json,src=apps.json \ + --tag=custom:16 \ + --file=images/layered/Containerfile . +``` + +#### 5. apps.json hash + +Note: When using branch references in `apps.json`, the hash only changes when the file content changes, not when an upstream app branch receives updates. This method works best when pinning specific commits or releases. + +```yaml +- name: Build Docker image + shell: sh + run: | + docker build \ + --build-arg=FRAPPE_PATH=https://github.com/frappe/frappe \ + --build-arg=FRAPPE_BRANCH=version-16 \ + --build-arg=CACHE_BUST="$(sha256sum apps.json | awk '{print $1}')" \ + --secret=id=apps_json,src=apps.json \ + --tag=custom:16 \ + --file=images/layered/Containerfile . +``` From 0b835b0819c7a884da0be6df3564f0b26cfd14ed Mon Sep 17 00:00:00 2001 From: jslocomotor <210083531+jslocomotor@users.noreply.github.com> Date: Mon, 27 Apr 2026 21:56:00 +0200 Subject: [PATCH 240/279] docs(production): add reference to CACHE_BUST explanation --- docs/02-setup/02-build-setup.md | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/docs/02-setup/02-build-setup.md b/docs/02-setup/02-build-setup.md index 0bf47810..326de9bf 100644 --- a/docs/02-setup/02-build-setup.md +++ b/docs/02-setup/02-build-setup.md @@ -84,21 +84,21 @@ See [Automated Builds and Deployment](../03-production/06-automated-builds-and-d ## Build args, secrets and flags -| Variable | Purpose | -| -------------------- | ----------------------------------------------------------------------------------------------- | -| **Frappe Framework** | | -| FRAPPE_PATH | Repository URL for Frappe framework source code. Defaults to | -| FRAPPE_BRANCH | Branch to use for Frappe framework. Defaults to version-16 | -| **Custom Apps** | | -| CACHE_BUST | Can be used to invalidate the cached layer when `apps_json` is passed as a secret. | -| (secret) apps_json | Passed via `--secret=id=apps_json,src=apps.json`. Never use `--build-arg` for this file. | -| **Dependencies** | | -| PYTHON_VERSION | Python version for the base image | -| NODE_VERSION | Node.js version | -| WKHTMLTOPDF_VERSION | wkhtmltopdf version | -| **bench only** | | -| DEBIAN_BASE | Debian base version for the bench image, defaults to `bookworm` | -| WKHTMLTOPDF_DISTRO | use the specified distro for debian package. Default is `bookworm` | +| Variable | Purpose | +| -------------------- | --------------------------------------------------------------------------------------------------------------------------------- | +| **Frappe Framework** | | +| FRAPPE_PATH | Repository URL for Frappe framework source code. Defaults to | +| FRAPPE_BRANCH | Branch to use for Frappe framework. Defaults to version-16 | +| **Custom Apps** | | +| CACHE_BUST | Can be used to invalidate the cached layer. See [Build Cache](../03-production/06-automated-builds-and-deployment.md#build-cache) | +| (secret) apps_json | Passed via `--secret=id=apps_json,src=apps.json`. Never use `--build-arg` for this file. | +| **Dependencies** | | +| PYTHON_VERSION | Python version for the base image | +| NODE_VERSION | Node.js version | +| WKHTMLTOPDF_VERSION | wkhtmltopdf version | +| **bench only** | | +| DEBIAN_BASE | Debian base version for the bench image, defaults to `bookworm` | +| WKHTMLTOPDF_DISTRO | use the specified distro for debian package. Default is `bookworm` | # Deploy the stack From 473f08a7f9ed672bd2a5782f9527c6fc6de00209 Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 28 Apr 2026 21:31:13 +0000 Subject: [PATCH 241/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 63ede817..b8f5a10e 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/02-setup/04-env-variables.md -ERPNEXT_VERSION=v16.15.1 +ERPNEXT_VERSION=v16.16.0 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index 0633f1ef..a2215a4a 100644 --- a/pwd.yml +++ b/pwd.yml @@ -1,6 +1,6 @@ services: backend: - image: frappe/erpnext:v16.15.1 + image: frappe/erpnext:v16.16.0 networks: - frappe_network deploy: @@ -16,7 +16,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v16.15.1 + image: frappe/erpnext:v16.16.0 networks: - frappe_network deploy: @@ -45,7 +45,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v16.15.1 + image: frappe/erpnext:v16.16.0 networks: - frappe_network deploy: @@ -101,7 +101,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v16.15.1 + image: frappe/erpnext:v16.16.0 networks: - frappe_network depends_on: @@ -127,7 +127,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v16.15.1 + image: frappe/erpnext:v16.16.0 networks: - frappe_network deploy: @@ -146,7 +146,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v16.15.1 + image: frappe/erpnext:v16.16.0 networks: - frappe_network deploy: @@ -183,7 +183,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v16.15.1 + image: frappe/erpnext:v16.16.0 networks: - frappe_network deploy: @@ -197,7 +197,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v16.15.1 + image: frappe/erpnext:v16.16.0 networks: - frappe_network deploy: From 12e6e821bcf22b8bdb8a896fec154901d89fdb1b Mon Sep 17 00:00:00 2001 From: jslocomotor <210083531+jslocomotor@users.noreply.github.com> Date: Wed, 29 Apr 2026 18:57:49 +0200 Subject: [PATCH 242/279] feat(compose): add migrator service override and documentation --- docs/02-setup/05-overrides.md | 6 ++- .../06-automated-builds-and-deployment.md | 19 ++++++++ overrides/compose.migrator.yaml | 45 +++++++++++++++++++ 3 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 overrides/compose.migrator.yaml diff --git a/docs/02-setup/05-overrides.md b/docs/02-setup/05-overrides.md index c81bf153..f10c6045 100644 --- a/docs/02-setup/05-overrides.md +++ b/docs/02-setup/05-overrides.md @@ -24,8 +24,10 @@ docker compose -f compose.yaml -f overrides/compose.mariadb.yaml -f overrides/co | compose.nginxproxy.yaml | Uses nginx-proxy as HTTP reverse proxy on port `:80` | Set `NGINX_PROXY_HOSTS`. Use with `compose.nginxproxy-ssl.yaml` for HTTPS. You can change the published port by setting `HTTP_PUBLISH_PORT` | | compose.nginxproxy-ssl.yaml | Adds acme-companion for HTTPS on port `:443` with automatic certificates | Requires `compose.nginxproxy.yaml`. Set `NGINX_PROXY_HOSTS` and `LETSENCRYPT_EMAIL`. `HTTP_PUBLISH_PORT` and `HTTPS_PUBLISH_PORT` can be set. | | **Redis** | | | -| compose.redis.yaml | Adds Redis service for caching and background job queuing | -| **TBD** | **The following overrides are available but lack documentation. If you use them and understand their purpose, please consider contributing to this documentation.** | +| compose.redis.yaml | Adds Redis service for caching and background job queuing | | +| **Services** | | | +| compose.migrator.yaml | Runs a dedicated migration container performing `bench migrate` on a site at every start | Set `SITE_NAME` | +| **TBD** | **The following overrides are available but lack documentation. If you use them and understand their purpose, please consider contributing to this documentation.** | | | compose.backup-cron.yaml | | | | compose.custom-domain-ssl.yaml | | | | compose.custom-domain.yaml | | | diff --git a/docs/03-production/06-automated-builds-and-deployment.md b/docs/03-production/06-automated-builds-and-deployment.md index 85113f51..1b71613b 100644 --- a/docs/03-production/06-automated-builds-and-deployment.md +++ b/docs/03-production/06-automated-builds-and-deployment.md @@ -126,3 +126,22 @@ Note: When using branch references in `apps.json`, the hash only changes when th --tag=custom:16 \ --file=images/layered/Containerfile . ``` + +## Automated deployment + +### Automate site migration + +After updating a custom image or deploying new app versions, a database migration +must be executed using `bench migrate`. + +Without running migrations, the site may become inconsistent or fail to start properly. + +For automated deployments, this step should not be performed manually. + +Consider using the dedicated `migrator` service provided as a Compose override. +It ensures that migrations are executed automatically when the stack starts. + +This approach is especially useful in CI/CD pipelines where no interactive access +to the backend container is available. + +See [Compose override](../../overrides/compose.migrator.yaml) diff --git a/overrides/compose.migrator.yaml b/overrides/compose.migrator.yaml new file mode 100644 index 00000000..aebc30a8 --- /dev/null +++ b/overrides/compose.migrator.yaml @@ -0,0 +1,45 @@ +# Provides a service for automated migration of a given site. +# Add SITE_NAME to .env + +# Compose extension fields of base compose.yaml. See https://github.com/frappe/frappe_docker/blob/main/compose.yaml +# Needed for merging compose files. +x-customizable-image: &customizable_image + # By default the image used only contains the `frappe` and `erpnext` apps. + # See https://github.com/frappe/frappe_docker/blob/main/docs/02-setup/02-build-setup.md#define-custom-apps + # about using custom images. + image: ${CUSTOM_IMAGE:-frappe/erpnext}:${CUSTOM_TAG:-$ERPNEXT_VERSION} + pull_policy: ${PULL_POLICY:-always} + restart: ${RESTART_POLICY:-unless-stopped} + +x-depends-on-configurator: &depends_on_configurator + depends_on: + configurator: + condition: service_completed_successfully + +x-backend-defaults: &backend_defaults + <<: [*depends_on_configurator, *customizable_image] + volumes: + - sites:/home/frappe/frappe-bench/sites + +services: + migrator: + <<: *backend_defaults + platform: linux/amd64 + entrypoint: + - bash + - -c + command: + - > + if [ -z "$$SITE_NAME" ]; then + echo "[migrator] SITE_NAME is not set"; + exit 1; + fi; + if [ -d "sites/$$SITE_NAME" ]; then + echo "[migrator] Migrating $$SITE_NAME"; + bench --site $$SITE_NAME migrate; + else + echo "[migrator] Site $$SITE_NAME not found, skipping migrate"; + fi + environment: + SITE_NAME: ${SITE_NAME} + restart: on-failure From 64e6536592bbdefc3ec046bb0bfa2916debc3ba6 Mon Sep 17 00:00:00 2001 From: dandax123 Date: Wed, 29 Apr 2026 14:16:56 +0200 Subject: [PATCH 243/279] fix(assets): link assets at container init --- images/custom/Containerfile | 12 ++++++++++++ images/layered/Containerfile | 12 ++++++++++++ images/production/Containerfile | 12 ++++++++++++ resources/core/main-entrypoint.sh | 12 ++++++++++++ 4 files changed, 48 insertions(+) create mode 100755 resources/core/main-entrypoint.sh diff --git a/images/custom/Containerfile b/images/custom/Containerfile index c99ff880..2ecb06d7 100644 --- a/images/custom/Containerfile +++ b/images/custom/Containerfile @@ -146,11 +146,23 @@ COPY --from=builder --chown=frappe:frappe /home/frappe/frappe-bench /home/frappe WORKDIR /home/frappe/frappe-bench +# Move assets to image-layer storage +RUN cp -r /home/frappe/frappe-bench/sites/assets /home/frappe/frappe-bench/assets && \ + rm -rf /home/frappe/frappe-bench/sites/assets + VOLUME [ \ "/home/frappe/frappe-bench/sites", \ "/home/frappe/frappe-bench/logs" \ ] +USER root +# This entrypoint script link build assets of the image to the mounted sites volume at container initialization +COPY resources/core/main-entrypoint.sh /usr/local/bin/entrypoint.sh +RUN chmod +x /usr/local/bin/entrypoint.sh + +USER frappe +ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] + CMD [ \ "/home/frappe/frappe-bench/env/bin/gunicorn", \ "--chdir=/home/frappe/frappe-bench/sites", \ diff --git a/images/layered/Containerfile b/images/layered/Containerfile index 0048930f..7482280c 100644 --- a/images/layered/Containerfile +++ b/images/layered/Containerfile @@ -35,11 +35,23 @@ COPY --from=builder --chown=frappe:frappe /home/frappe/frappe-bench /home/frappe WORKDIR /home/frappe/frappe-bench +# Move assets to image-layer storage +RUN cp -r /home/frappe/frappe-bench/sites/assets /home/frappe/frappe-bench/assets && \ + rm -rf /home/frappe/frappe-bench/sites/assets + VOLUME [ \ "/home/frappe/frappe-bench/sites", \ "/home/frappe/frappe-bench/logs" \ ] +USER root +# This entrypoint script link build assets of the image to the mounted sites volume at container initialization +COPY resources/core/main-entrypoint.sh /usr/local/bin/entrypoint.sh +RUN chmod +x /usr/local/bin/entrypoint.sh + +USER frappe +ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] + CMD [ \ "/home/frappe/frappe-bench/env/bin/gunicorn", \ "--chdir=/home/frappe/frappe-bench/sites", \ diff --git a/images/production/Containerfile b/images/production/Containerfile index 48df0d9d..f95a9703 100644 --- a/images/production/Containerfile +++ b/images/production/Containerfile @@ -136,11 +136,23 @@ COPY --from=builder --chown=frappe:frappe /home/frappe/frappe-bench /home/frappe WORKDIR /home/frappe/frappe-bench +# Move assets to image-layer storage +RUN cp -r /home/frappe/frappe-bench/sites/assets /home/frappe/frappe-bench/assets && \ + rm -rf /home/frappe/frappe-bench/sites/assets + VOLUME [ \ "/home/frappe/frappe-bench/sites", \ "/home/frappe/frappe-bench/logs" \ ] +USER root +# This entrypoint script link build assets of the image to the mounted sites volume at container initialization +COPY resources/core/main-entrypoint.sh /usr/local/bin/entrypoint.sh +RUN chmod +x /usr/local/bin/entrypoint.sh + +USER frappe +ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] + CMD [ \ "/home/frappe/frappe-bench/env/bin/gunicorn", \ "--chdir=/home/frappe/frappe-bench/sites", \ diff --git a/resources/core/main-entrypoint.sh b/resources/core/main-entrypoint.sh new file mode 100755 index 00000000..d1e89601 --- /dev/null +++ b/resources/core/main-entrypoint.sh @@ -0,0 +1,12 @@ +#!/bin/bash +set -e + +ASSETS_PATH="/home/frappe/frappe-bench/sites/assets" +BAKED_PATH="/home/frappe/frappe-bench/assets" + +echo "Linking fresh assets to volume..." +rm -rf "$ASSETS_PATH" +mkdir -p "$(dirname "$ASSETS_PATH")" +ln -s "$BAKED_PATH" "$ASSETS_PATH" + +exec "$@" From ae221ebf7ab6b7db467a7c9242801188cb1673f4 Mon Sep 17 00:00:00 2001 From: jslocomotor <210083531+jslocomotor@users.noreply.github.com> Date: Thu, 30 Apr 2026 23:15:58 +0200 Subject: [PATCH 244/279] feat(migrator): add multi-site support to migration --- docs/02-setup/05-overrides.md | 2 +- overrides/compose.migrator.yaml | 23 +++++++++++------------ 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/docs/02-setup/05-overrides.md b/docs/02-setup/05-overrides.md index f10c6045..ee3f64af 100644 --- a/docs/02-setup/05-overrides.md +++ b/docs/02-setup/05-overrides.md @@ -26,7 +26,7 @@ docker compose -f compose.yaml -f overrides/compose.mariadb.yaml -f overrides/co | **Redis** | | | | compose.redis.yaml | Adds Redis service for caching and background job queuing | | | **Services** | | | -| compose.migrator.yaml | Runs a dedicated migration container performing `bench migrate` on a site at every start | Set `SITE_NAME` | +| compose.migrator.yaml | Runs a dedicated migration container performing `bench --site all migrate` on a site at every start | Control via `MIGRATE_SITES` - defaults to true | | **TBD** | **The following overrides are available but lack documentation. If you use them and understand their purpose, please consider contributing to this documentation.** | | | compose.backup-cron.yaml | | | | compose.custom-domain-ssl.yaml | | | diff --git a/overrides/compose.migrator.yaml b/overrides/compose.migrator.yaml index aebc30a8..8a96107f 100644 --- a/overrides/compose.migrator.yaml +++ b/overrides/compose.migrator.yaml @@ -1,5 +1,4 @@ # Provides a service for automated migration of a given site. -# Add SITE_NAME to .env # Compose extension fields of base compose.yaml. See https://github.com/frappe/frappe_docker/blob/main/compose.yaml # Needed for merging compose files. @@ -30,16 +29,16 @@ services: - -c command: - > - if [ -z "$$SITE_NAME" ]; then - echo "[migrator] SITE_NAME is not set"; - exit 1; + if [ "$$MIGRATE_SITES" != "true" ]; then + echo "[migrator] Migration disabled"; + exit 0; fi; - if [ -d "sites/$$SITE_NAME" ]; then - echo "[migrator] Migrating $$SITE_NAME"; - bench --site $$SITE_NAME migrate; - else - echo "[migrator] Site $$SITE_NAME not found, skipping migrate"; - fi + if [ -z "$$(find sites -mindepth 2 -maxdepth 2 -name site_config.json 2>/dev/null)" ]; then + echo "[migrator] No sites found, skipping migration"; + exit 0; + fi; + echo "[migrator] Migrating all sites"; + bench --site all migrate; environment: - SITE_NAME: ${SITE_NAME} - restart: on-failure + MIGRATE_SITES: ${MIGRATE_SITES:-true} + restart: on-failure:5 From 092a3769b15633fdeba5832efdc876d5106c72ee Mon Sep 17 00:00:00 2001 From: jslocomotor <210083531+jslocomotor@users.noreply.github.com> Date: Thu, 30 Apr 2026 23:33:05 +0200 Subject: [PATCH 245/279] docs(overrides): corrected migrator description --- docs/02-setup/05-overrides.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/02-setup/05-overrides.md b/docs/02-setup/05-overrides.md index ee3f64af..2cbd9691 100644 --- a/docs/02-setup/05-overrides.md +++ b/docs/02-setup/05-overrides.md @@ -26,7 +26,7 @@ docker compose -f compose.yaml -f overrides/compose.mariadb.yaml -f overrides/co | **Redis** | | | | compose.redis.yaml | Adds Redis service for caching and background job queuing | | | **Services** | | | -| compose.migrator.yaml | Runs a dedicated migration container performing `bench --site all migrate` on a site at every start | Control via `MIGRATE_SITES` - defaults to true | +| compose.migrator.yaml | Runs a dedicated migration container performing `bench --site all migrate` on all sites at every start | Control migration intent with `MIGRATE_SITES` - defaults to true | | **TBD** | **The following overrides are available but lack documentation. If you use them and understand their purpose, please consider contributing to this documentation.** | | | compose.backup-cron.yaml | | | | compose.custom-domain-ssl.yaml | | | From 9432daaaafce319077aa6cab2812cad7d5356942 Mon Sep 17 00:00:00 2001 From: jslocomotor <210083531+jslocomotor@users.noreply.github.com> Date: Sun, 3 May 2026 21:06:04 +0200 Subject: [PATCH 246/279] docs(env): added migration service variable description --- docs/02-setup/04-env-variables.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/02-setup/04-env-variables.md b/docs/02-setup/04-env-variables.md index ab07da67..561ee6d2 100644 --- a/docs/02-setup/04-env-variables.md +++ b/docs/02-setup/04-env-variables.md @@ -140,3 +140,11 @@ Use these variables when running behind a reverse proxy or load balancer: | `UPSTREAM_REAL_IP_ADDRESS` | Trusted upstream IP address for real IP detection | `127.0.0.1` | | `UPSTREAM_REAL_IP_HEADER` | Request header containing client IP | `X-Forwarded-For` | | `UPSTREAM_REAL_IP_RECURSIVE` | Enable recursive IP search | `off` | + +--- + +## Migration Service + +| Variable | Purpose | Default | Allowed Values | +| --------------- | ------------------------------- | -------------------------- | ---------------- | +| `MIGRATE_SITES` | Switch auto migration on or off | `true` - auto migration on | `true` , `false` | From edfd8f0755a22c53a7f45b472d5746a10ba80d61 Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 5 May 2026 17:03:26 +0000 Subject: [PATCH 247/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index b8f5a10e..899486dd 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/02-setup/04-env-variables.md -ERPNEXT_VERSION=v16.16.0 +ERPNEXT_VERSION=v16.17.0 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index a2215a4a..6997042d 100644 --- a/pwd.yml +++ b/pwd.yml @@ -1,6 +1,6 @@ services: backend: - image: frappe/erpnext:v16.16.0 + image: frappe/erpnext:v16.17.0 networks: - frappe_network deploy: @@ -16,7 +16,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v16.16.0 + image: frappe/erpnext:v16.17.0 networks: - frappe_network deploy: @@ -45,7 +45,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v16.16.0 + image: frappe/erpnext:v16.17.0 networks: - frappe_network deploy: @@ -101,7 +101,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v16.16.0 + image: frappe/erpnext:v16.17.0 networks: - frappe_network depends_on: @@ -127,7 +127,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v16.16.0 + image: frappe/erpnext:v16.17.0 networks: - frappe_network deploy: @@ -146,7 +146,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v16.16.0 + image: frappe/erpnext:v16.17.0 networks: - frappe_network deploy: @@ -183,7 +183,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v16.16.0 + image: frappe/erpnext:v16.17.0 networks: - frappe_network deploy: @@ -197,7 +197,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v16.16.0 + image: frappe/erpnext:v16.17.0 networks: - frappe_network deploy: From 373e6c1e203114b0a0faa65a0e099dba6ce6d942 Mon Sep 17 00:00:00 2001 From: Ingo Schuck Date: Wed, 6 May 2026 19:35:03 +0200 Subject: [PATCH 248/279] Fix entrypoint.sh permission --- images/layered/Containerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/images/layered/Containerfile b/images/layered/Containerfile index 7482280c..18511c61 100644 --- a/images/layered/Containerfile +++ b/images/layered/Containerfile @@ -47,7 +47,7 @@ VOLUME [ \ USER root # This entrypoint script link build assets of the image to the mounted sites volume at container initialization COPY resources/core/main-entrypoint.sh /usr/local/bin/entrypoint.sh -RUN chmod +x /usr/local/bin/entrypoint.sh +RUN chmod ugo+rx /usr/local/bin/entrypoint.sh USER frappe ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] From 5d9f2e41a04d7e9eccb2ceb9c3c3791dc406f562 Mon Sep 17 00:00:00 2001 From: jslocomotor <210083531+jslocomotor@users.noreply.github.com> Date: Wed, 6 May 2026 20:30:52 +0200 Subject: [PATCH 249/279] feat(images): toggle chromium installation --- docs/02-setup/02-build-setup.md | 1 + images/bench/Dockerfile | 8 ++++++-- images/custom/Containerfile | 9 +++++++-- images/production/Containerfile | 9 +++++++-- 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/docs/02-setup/02-build-setup.md b/docs/02-setup/02-build-setup.md index 326de9bf..09cef899 100644 --- a/docs/02-setup/02-build-setup.md +++ b/docs/02-setup/02-build-setup.md @@ -96,6 +96,7 @@ See [Automated Builds and Deployment](../03-production/06-automated-builds-and-d | PYTHON_VERSION | Python version for the base image | | NODE_VERSION | Node.js version | | WKHTMLTOPDF_VERSION | wkhtmltopdf version | +| INSTALL_CHROMIUM | Configure chromium installation, defaults to `true` - needed for Frappe Workbench version >15 | | **bench only** | | | DEBIAN_BASE | Debian base version for the bench image, defaults to `bookworm` | | WKHTMLTOPDF_DISTRO | use the specified distro for debian package. Default is `bookworm` | diff --git a/images/bench/Dockerfile b/images/bench/Dockerfile index 9c21345d..1cb0b278 100644 --- a/images/bench/Dockerfile +++ b/images/bench/Dockerfile @@ -4,6 +4,7 @@ LABEL author=frappΓ© ARG GIT_REPO=https://github.com/frappe/bench.git ARG GIT_BRANCH=v5.x +ARG INSTALL_CHROMIUM=true RUN apt-get update \ && DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \ @@ -23,8 +24,6 @@ RUN apt-get update \ libharfbuzz0b \ libpangoft2-1.0-0 \ libpangocairo-1.0-0 \ - #Chromium - chromium-headless-shell \ # to work inside the container locales \ build-essential \ @@ -75,6 +74,11 @@ RUN apt-get update \ file \ # For MIME type detection media-types \ + # Chromium + && if [ "$INSTALL_CHROMIUM" = "true" ]; then \ + DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \ + chromium-headless-shell; \ + fi \ && rm -rf /var/lib/apt/lists/* RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen \ diff --git a/images/custom/Containerfile b/images/custom/Containerfile index 2ecb06d7..5f8072f6 100644 --- a/images/custom/Containerfile +++ b/images/custom/Containerfile @@ -8,6 +8,8 @@ COPY resources/core/nginx/security_headers.conf /etc/nginx/snippets/security_hea ARG WKHTMLTOPDF_VERSION=0.12.6.1-3 ARG WKHTMLTOPDF_DISTRO=bookworm +ARG INSTALL_CHROMIUM=true + ARG NODE_VERSION=24.13.0 ENV NVM_DIR=/home/frappe/.nvm ENV PATH=${NVM_DIR}/versions/node/v${NODE_VERSION}/bin/:${PATH} @@ -26,8 +28,6 @@ RUN useradd -ms /bin/bash frappe \ libharfbuzz0b \ libpangoft2-1.0-0 \ libpangocairo-1.0-0 \ - #Chromium - chromium-headless-shell \ # For backups restic \ gpg \ @@ -62,6 +62,11 @@ RUN useradd -ms /bin/bash frappe \ && curl -sLO https://github.com/wkhtmltopdf/packaging/releases/download/$WKHTMLTOPDF_VERSION/$downloaded_file \ && apt-get install -y ./$downloaded_file \ && rm $downloaded_file \ + # Chromium + && if [ "$INSTALL_CHROMIUM" = "true" ]; then \ + DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \ + chromium-headless-shell; \ + fi \ # Clean up && rm -rf /var/lib/apt/lists/* \ && rm -fr /etc/nginx/sites-enabled/default \ diff --git a/images/production/Containerfile b/images/production/Containerfile index f95a9703..e2a2f3ee 100644 --- a/images/production/Containerfile +++ b/images/production/Containerfile @@ -4,6 +4,8 @@ FROM python:${PYTHON_VERSION}-slim-${DEBIAN_BASE} AS base ARG WKHTMLTOPDF_VERSION=0.12.6.1-3 ARG WKHTMLTOPDF_DISTRO=bookworm +ARG INSTALL_CHROMIUM=true + ARG NODE_VERSION=24.13.0 ENV NVM_DIR=/home/frappe/.nvm ENV PATH=${NVM_DIR}/versions/node/v${NODE_VERSION}/bin/:${PATH} @@ -22,8 +24,6 @@ RUN useradd -ms /bin/bash frappe \ libharfbuzz0b \ libpangoft2-1.0-0 \ libpangocairo-1.0-0 \ - #Chromium - chromium-headless-shell \ # For backups restic \ gpg \ @@ -58,6 +58,11 @@ RUN useradd -ms /bin/bash frappe \ && curl -sLO https://github.com/wkhtmltopdf/packaging/releases/download/$WKHTMLTOPDF_VERSION/$downloaded_file \ && apt-get install -y ./$downloaded_file \ && rm $downloaded_file \ + # Chromium + && if [ "$INSTALL_CHROMIUM" = "true" ]; then \ + DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \ + chromium-headless-shell; \ + fi \ # Clean up && rm -rf /var/lib/apt/lists/* \ && rm -fr /etc/nginx/sites-enabled/default \ From 2af7b06f8d9aa20334c8acb7cbf5ab393f39ab15 Mon Sep 17 00:00:00 2001 From: jslocomotor <210083531+jslocomotor@users.noreply.github.com> Date: Thu, 7 May 2026 14:03:12 +0200 Subject: [PATCH 250/279] feat(images): permissive boolean check for INSTALL_CHROMIUM --- images/bench/Dockerfile | 2 +- images/custom/Containerfile | 2 +- images/production/Containerfile | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/images/bench/Dockerfile b/images/bench/Dockerfile index 1cb0b278..2b2540b5 100644 --- a/images/bench/Dockerfile +++ b/images/bench/Dockerfile @@ -75,7 +75,7 @@ RUN apt-get update \ # For MIME type detection media-types \ # Chromium - && if [ "$INSTALL_CHROMIUM" = "true" ]; then \ + && if [ "$INSTALL_CHROMIUM" != "false" ]; then \ DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \ chromium-headless-shell; \ fi \ diff --git a/images/custom/Containerfile b/images/custom/Containerfile index 5f8072f6..084104b3 100644 --- a/images/custom/Containerfile +++ b/images/custom/Containerfile @@ -63,7 +63,7 @@ RUN useradd -ms /bin/bash frappe \ && apt-get install -y ./$downloaded_file \ && rm $downloaded_file \ # Chromium - && if [ "$INSTALL_CHROMIUM" = "true" ]; then \ + && if [ "$INSTALL_CHROMIUM" != "false" ]; then \ DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \ chromium-headless-shell; \ fi \ diff --git a/images/production/Containerfile b/images/production/Containerfile index e2a2f3ee..983dc2ea 100644 --- a/images/production/Containerfile +++ b/images/production/Containerfile @@ -59,7 +59,7 @@ RUN useradd -ms /bin/bash frappe \ && apt-get install -y ./$downloaded_file \ && rm $downloaded_file \ # Chromium - && if [ "$INSTALL_CHROMIUM" = "true" ]; then \ + && if [ "$INSTALL_CHROMIUM" != "false" ]; then \ DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \ chromium-headless-shell; \ fi \ From c302af9dd5f3bcccfdcee62f54693fb7120199ce Mon Sep 17 00:00:00 2001 From: jslocomotor <210083531+jslocomotor@users.noreply.github.com> Date: Wed, 6 May 2026 20:30:52 +0200 Subject: [PATCH 251/279] feat(images): toggle chromium installation --- docs/02-setup/02-build-setup.md | 1 + images/bench/Dockerfile | 8 ++++++-- images/custom/Containerfile | 9 +++++++-- images/production/Containerfile | 9 +++++++-- 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/docs/02-setup/02-build-setup.md b/docs/02-setup/02-build-setup.md index 326de9bf..09cef899 100644 --- a/docs/02-setup/02-build-setup.md +++ b/docs/02-setup/02-build-setup.md @@ -96,6 +96,7 @@ See [Automated Builds and Deployment](../03-production/06-automated-builds-and-d | PYTHON_VERSION | Python version for the base image | | NODE_VERSION | Node.js version | | WKHTMLTOPDF_VERSION | wkhtmltopdf version | +| INSTALL_CHROMIUM | Configure chromium installation, defaults to `true` - needed for Frappe Workbench version >15 | | **bench only** | | | DEBIAN_BASE | Debian base version for the bench image, defaults to `bookworm` | | WKHTMLTOPDF_DISTRO | use the specified distro for debian package. Default is `bookworm` | diff --git a/images/bench/Dockerfile b/images/bench/Dockerfile index 9c21345d..1cb0b278 100644 --- a/images/bench/Dockerfile +++ b/images/bench/Dockerfile @@ -4,6 +4,7 @@ LABEL author=frappΓ© ARG GIT_REPO=https://github.com/frappe/bench.git ARG GIT_BRANCH=v5.x +ARG INSTALL_CHROMIUM=true RUN apt-get update \ && DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \ @@ -23,8 +24,6 @@ RUN apt-get update \ libharfbuzz0b \ libpangoft2-1.0-0 \ libpangocairo-1.0-0 \ - #Chromium - chromium-headless-shell \ # to work inside the container locales \ build-essential \ @@ -75,6 +74,11 @@ RUN apt-get update \ file \ # For MIME type detection media-types \ + # Chromium + && if [ "$INSTALL_CHROMIUM" = "true" ]; then \ + DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \ + chromium-headless-shell; \ + fi \ && rm -rf /var/lib/apt/lists/* RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen \ diff --git a/images/custom/Containerfile b/images/custom/Containerfile index 2ecb06d7..5f8072f6 100644 --- a/images/custom/Containerfile +++ b/images/custom/Containerfile @@ -8,6 +8,8 @@ COPY resources/core/nginx/security_headers.conf /etc/nginx/snippets/security_hea ARG WKHTMLTOPDF_VERSION=0.12.6.1-3 ARG WKHTMLTOPDF_DISTRO=bookworm +ARG INSTALL_CHROMIUM=true + ARG NODE_VERSION=24.13.0 ENV NVM_DIR=/home/frappe/.nvm ENV PATH=${NVM_DIR}/versions/node/v${NODE_VERSION}/bin/:${PATH} @@ -26,8 +28,6 @@ RUN useradd -ms /bin/bash frappe \ libharfbuzz0b \ libpangoft2-1.0-0 \ libpangocairo-1.0-0 \ - #Chromium - chromium-headless-shell \ # For backups restic \ gpg \ @@ -62,6 +62,11 @@ RUN useradd -ms /bin/bash frappe \ && curl -sLO https://github.com/wkhtmltopdf/packaging/releases/download/$WKHTMLTOPDF_VERSION/$downloaded_file \ && apt-get install -y ./$downloaded_file \ && rm $downloaded_file \ + # Chromium + && if [ "$INSTALL_CHROMIUM" = "true" ]; then \ + DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \ + chromium-headless-shell; \ + fi \ # Clean up && rm -rf /var/lib/apt/lists/* \ && rm -fr /etc/nginx/sites-enabled/default \ diff --git a/images/production/Containerfile b/images/production/Containerfile index f95a9703..e2a2f3ee 100644 --- a/images/production/Containerfile +++ b/images/production/Containerfile @@ -4,6 +4,8 @@ FROM python:${PYTHON_VERSION}-slim-${DEBIAN_BASE} AS base ARG WKHTMLTOPDF_VERSION=0.12.6.1-3 ARG WKHTMLTOPDF_DISTRO=bookworm +ARG INSTALL_CHROMIUM=true + ARG NODE_VERSION=24.13.0 ENV NVM_DIR=/home/frappe/.nvm ENV PATH=${NVM_DIR}/versions/node/v${NODE_VERSION}/bin/:${PATH} @@ -22,8 +24,6 @@ RUN useradd -ms /bin/bash frappe \ libharfbuzz0b \ libpangoft2-1.0-0 \ libpangocairo-1.0-0 \ - #Chromium - chromium-headless-shell \ # For backups restic \ gpg \ @@ -58,6 +58,11 @@ RUN useradd -ms /bin/bash frappe \ && curl -sLO https://github.com/wkhtmltopdf/packaging/releases/download/$WKHTMLTOPDF_VERSION/$downloaded_file \ && apt-get install -y ./$downloaded_file \ && rm $downloaded_file \ + # Chromium + && if [ "$INSTALL_CHROMIUM" = "true" ]; then \ + DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \ + chromium-headless-shell; \ + fi \ # Clean up && rm -rf /var/lib/apt/lists/* \ && rm -fr /etc/nginx/sites-enabled/default \ From 0a04e5ecd26b89382a8c3c81685b928359c90e5d Mon Sep 17 00:00:00 2001 From: jslocomotor <210083531+jslocomotor@users.noreply.github.com> Date: Thu, 7 May 2026 14:03:12 +0200 Subject: [PATCH 252/279] feat(images): permissive boolean check for INSTALL_CHROMIUM --- images/bench/Dockerfile | 2 +- images/custom/Containerfile | 2 +- images/production/Containerfile | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/images/bench/Dockerfile b/images/bench/Dockerfile index 1cb0b278..2b2540b5 100644 --- a/images/bench/Dockerfile +++ b/images/bench/Dockerfile @@ -75,7 +75,7 @@ RUN apt-get update \ # For MIME type detection media-types \ # Chromium - && if [ "$INSTALL_CHROMIUM" = "true" ]; then \ + && if [ "$INSTALL_CHROMIUM" != "false" ]; then \ DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \ chromium-headless-shell; \ fi \ diff --git a/images/custom/Containerfile b/images/custom/Containerfile index 5f8072f6..084104b3 100644 --- a/images/custom/Containerfile +++ b/images/custom/Containerfile @@ -63,7 +63,7 @@ RUN useradd -ms /bin/bash frappe \ && apt-get install -y ./$downloaded_file \ && rm $downloaded_file \ # Chromium - && if [ "$INSTALL_CHROMIUM" = "true" ]; then \ + && if [ "$INSTALL_CHROMIUM" != "false" ]; then \ DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \ chromium-headless-shell; \ fi \ diff --git a/images/production/Containerfile b/images/production/Containerfile index e2a2f3ee..983dc2ea 100644 --- a/images/production/Containerfile +++ b/images/production/Containerfile @@ -59,7 +59,7 @@ RUN useradd -ms /bin/bash frappe \ && apt-get install -y ./$downloaded_file \ && rm $downloaded_file \ # Chromium - && if [ "$INSTALL_CHROMIUM" = "true" ]; then \ + && if [ "$INSTALL_CHROMIUM" != "false" ]; then \ DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \ chromium-headless-shell; \ fi \ From c7ac6b7666eb4ae9bd40e9665c23f27a2cedb3d9 Mon Sep 17 00:00:00 2001 From: Ingo Schuck Date: Thu, 7 May 2026 21:27:16 +0200 Subject: [PATCH 253/279] fix all entrypoint.sh permissions to 755 --- images/custom/Containerfile | 2 +- images/layered/Containerfile | 2 +- images/production/Containerfile | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/images/custom/Containerfile b/images/custom/Containerfile index 084104b3..9528688b 100644 --- a/images/custom/Containerfile +++ b/images/custom/Containerfile @@ -163,7 +163,7 @@ VOLUME [ \ USER root # This entrypoint script link build assets of the image to the mounted sites volume at container initialization COPY resources/core/main-entrypoint.sh /usr/local/bin/entrypoint.sh -RUN chmod +x /usr/local/bin/entrypoint.sh +RUN chmod 755 /usr/local/bin/entrypoint.sh USER frappe ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] diff --git a/images/layered/Containerfile b/images/layered/Containerfile index 18511c61..c3326ddd 100644 --- a/images/layered/Containerfile +++ b/images/layered/Containerfile @@ -47,7 +47,7 @@ VOLUME [ \ USER root # This entrypoint script link build assets of the image to the mounted sites volume at container initialization COPY resources/core/main-entrypoint.sh /usr/local/bin/entrypoint.sh -RUN chmod ugo+rx /usr/local/bin/entrypoint.sh +RUN chmod 755 /usr/local/bin/entrypoint.sh USER frappe ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] diff --git a/images/production/Containerfile b/images/production/Containerfile index 983dc2ea..7ad4089d 100644 --- a/images/production/Containerfile +++ b/images/production/Containerfile @@ -82,6 +82,7 @@ RUN useradd -ms /bin/bash frappe \ COPY resources/core/nginx/nginx-template.conf /templates/nginx/frappe.conf.template COPY resources/core/nginx/nginx-entrypoint.sh /usr/local/bin/nginx-entrypoint.sh COPY resources/core/nginx/security_headers.conf /etc/nginx/snippets/security_headers.conf +RUN chmod 755 /usr/local/bin/nginx-entrypoint.sh FROM base AS build @@ -153,7 +154,7 @@ VOLUME [ \ USER root # This entrypoint script link build assets of the image to the mounted sites volume at container initialization COPY resources/core/main-entrypoint.sh /usr/local/bin/entrypoint.sh -RUN chmod +x /usr/local/bin/entrypoint.sh +RUN chmod 755 /usr/local/bin/entrypoint.sh USER frappe ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] From 93ade44c6b5f25b409c41f04c18e22737e74d69b Mon Sep 17 00:00:00 2001 From: Ingo Schuck Date: Thu, 7 May 2026 21:50:12 +0200 Subject: [PATCH 254/279] Revert "fix all entrypoint.sh permissions to 755" This reverts commit c7ac6b7666eb4ae9bd40e9665c23f27a2cedb3d9. --- images/custom/Containerfile | 2 +- images/layered/Containerfile | 2 +- images/production/Containerfile | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/images/custom/Containerfile b/images/custom/Containerfile index 9528688b..084104b3 100644 --- a/images/custom/Containerfile +++ b/images/custom/Containerfile @@ -163,7 +163,7 @@ VOLUME [ \ USER root # This entrypoint script link build assets of the image to the mounted sites volume at container initialization COPY resources/core/main-entrypoint.sh /usr/local/bin/entrypoint.sh -RUN chmod 755 /usr/local/bin/entrypoint.sh +RUN chmod +x /usr/local/bin/entrypoint.sh USER frappe ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] diff --git a/images/layered/Containerfile b/images/layered/Containerfile index c3326ddd..18511c61 100644 --- a/images/layered/Containerfile +++ b/images/layered/Containerfile @@ -47,7 +47,7 @@ VOLUME [ \ USER root # This entrypoint script link build assets of the image to the mounted sites volume at container initialization COPY resources/core/main-entrypoint.sh /usr/local/bin/entrypoint.sh -RUN chmod 755 /usr/local/bin/entrypoint.sh +RUN chmod ugo+rx /usr/local/bin/entrypoint.sh USER frappe ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] diff --git a/images/production/Containerfile b/images/production/Containerfile index 7ad4089d..983dc2ea 100644 --- a/images/production/Containerfile +++ b/images/production/Containerfile @@ -82,7 +82,6 @@ RUN useradd -ms /bin/bash frappe \ COPY resources/core/nginx/nginx-template.conf /templates/nginx/frappe.conf.template COPY resources/core/nginx/nginx-entrypoint.sh /usr/local/bin/nginx-entrypoint.sh COPY resources/core/nginx/security_headers.conf /etc/nginx/snippets/security_headers.conf -RUN chmod 755 /usr/local/bin/nginx-entrypoint.sh FROM base AS build @@ -154,7 +153,7 @@ VOLUME [ \ USER root # This entrypoint script link build assets of the image to the mounted sites volume at container initialization COPY resources/core/main-entrypoint.sh /usr/local/bin/entrypoint.sh -RUN chmod 755 /usr/local/bin/entrypoint.sh +RUN chmod +x /usr/local/bin/entrypoint.sh USER frappe ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] From 8f4130b5d33d015bbdf6aab50d6a6210e4084862 Mon Sep 17 00:00:00 2001 From: Ingo Schuck Date: Thu, 7 May 2026 21:50:36 +0200 Subject: [PATCH 255/279] Revert "feat(images): permissive boolean check for INSTALL_CHROMIUM" This reverts commit 0a04e5ecd26b89382a8c3c81685b928359c90e5d. --- images/bench/Dockerfile | 2 +- images/custom/Containerfile | 2 +- images/production/Containerfile | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/images/bench/Dockerfile b/images/bench/Dockerfile index 2b2540b5..1cb0b278 100644 --- a/images/bench/Dockerfile +++ b/images/bench/Dockerfile @@ -75,7 +75,7 @@ RUN apt-get update \ # For MIME type detection media-types \ # Chromium - && if [ "$INSTALL_CHROMIUM" != "false" ]; then \ + && if [ "$INSTALL_CHROMIUM" = "true" ]; then \ DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \ chromium-headless-shell; \ fi \ diff --git a/images/custom/Containerfile b/images/custom/Containerfile index 084104b3..5f8072f6 100644 --- a/images/custom/Containerfile +++ b/images/custom/Containerfile @@ -63,7 +63,7 @@ RUN useradd -ms /bin/bash frappe \ && apt-get install -y ./$downloaded_file \ && rm $downloaded_file \ # Chromium - && if [ "$INSTALL_CHROMIUM" != "false" ]; then \ + && if [ "$INSTALL_CHROMIUM" = "true" ]; then \ DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \ chromium-headless-shell; \ fi \ diff --git a/images/production/Containerfile b/images/production/Containerfile index 983dc2ea..e2a2f3ee 100644 --- a/images/production/Containerfile +++ b/images/production/Containerfile @@ -59,7 +59,7 @@ RUN useradd -ms /bin/bash frappe \ && apt-get install -y ./$downloaded_file \ && rm $downloaded_file \ # Chromium - && if [ "$INSTALL_CHROMIUM" != "false" ]; then \ + && if [ "$INSTALL_CHROMIUM" = "true" ]; then \ DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \ chromium-headless-shell; \ fi \ From 09fcd3e83b6327d27afd174d23ec116917adf000 Mon Sep 17 00:00:00 2001 From: Ingo Schuck Date: Thu, 7 May 2026 21:50:56 +0200 Subject: [PATCH 256/279] Revert "feat(images): toggle chromium installation" This reverts commit c302af9dd5f3bcccfdcee62f54693fb7120199ce. --- docs/02-setup/02-build-setup.md | 1 - images/bench/Dockerfile | 8 ++------ images/custom/Containerfile | 9 ++------- images/production/Containerfile | 9 ++------- 4 files changed, 6 insertions(+), 21 deletions(-) diff --git a/docs/02-setup/02-build-setup.md b/docs/02-setup/02-build-setup.md index 09cef899..326de9bf 100644 --- a/docs/02-setup/02-build-setup.md +++ b/docs/02-setup/02-build-setup.md @@ -96,7 +96,6 @@ See [Automated Builds and Deployment](../03-production/06-automated-builds-and-d | PYTHON_VERSION | Python version for the base image | | NODE_VERSION | Node.js version | | WKHTMLTOPDF_VERSION | wkhtmltopdf version | -| INSTALL_CHROMIUM | Configure chromium installation, defaults to `true` - needed for Frappe Workbench version >15 | | **bench only** | | | DEBIAN_BASE | Debian base version for the bench image, defaults to `bookworm` | | WKHTMLTOPDF_DISTRO | use the specified distro for debian package. Default is `bookworm` | diff --git a/images/bench/Dockerfile b/images/bench/Dockerfile index 1cb0b278..9c21345d 100644 --- a/images/bench/Dockerfile +++ b/images/bench/Dockerfile @@ -4,7 +4,6 @@ LABEL author=frappΓ© ARG GIT_REPO=https://github.com/frappe/bench.git ARG GIT_BRANCH=v5.x -ARG INSTALL_CHROMIUM=true RUN apt-get update \ && DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \ @@ -24,6 +23,8 @@ RUN apt-get update \ libharfbuzz0b \ libpangoft2-1.0-0 \ libpangocairo-1.0-0 \ + #Chromium + chromium-headless-shell \ # to work inside the container locales \ build-essential \ @@ -74,11 +75,6 @@ RUN apt-get update \ file \ # For MIME type detection media-types \ - # Chromium - && if [ "$INSTALL_CHROMIUM" = "true" ]; then \ - DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \ - chromium-headless-shell; \ - fi \ && rm -rf /var/lib/apt/lists/* RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen \ diff --git a/images/custom/Containerfile b/images/custom/Containerfile index 5f8072f6..2ecb06d7 100644 --- a/images/custom/Containerfile +++ b/images/custom/Containerfile @@ -8,8 +8,6 @@ COPY resources/core/nginx/security_headers.conf /etc/nginx/snippets/security_hea ARG WKHTMLTOPDF_VERSION=0.12.6.1-3 ARG WKHTMLTOPDF_DISTRO=bookworm -ARG INSTALL_CHROMIUM=true - ARG NODE_VERSION=24.13.0 ENV NVM_DIR=/home/frappe/.nvm ENV PATH=${NVM_DIR}/versions/node/v${NODE_VERSION}/bin/:${PATH} @@ -28,6 +26,8 @@ RUN useradd -ms /bin/bash frappe \ libharfbuzz0b \ libpangoft2-1.0-0 \ libpangocairo-1.0-0 \ + #Chromium + chromium-headless-shell \ # For backups restic \ gpg \ @@ -62,11 +62,6 @@ RUN useradd -ms /bin/bash frappe \ && curl -sLO https://github.com/wkhtmltopdf/packaging/releases/download/$WKHTMLTOPDF_VERSION/$downloaded_file \ && apt-get install -y ./$downloaded_file \ && rm $downloaded_file \ - # Chromium - && if [ "$INSTALL_CHROMIUM" = "true" ]; then \ - DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \ - chromium-headless-shell; \ - fi \ # Clean up && rm -rf /var/lib/apt/lists/* \ && rm -fr /etc/nginx/sites-enabled/default \ diff --git a/images/production/Containerfile b/images/production/Containerfile index e2a2f3ee..f95a9703 100644 --- a/images/production/Containerfile +++ b/images/production/Containerfile @@ -4,8 +4,6 @@ FROM python:${PYTHON_VERSION}-slim-${DEBIAN_BASE} AS base ARG WKHTMLTOPDF_VERSION=0.12.6.1-3 ARG WKHTMLTOPDF_DISTRO=bookworm -ARG INSTALL_CHROMIUM=true - ARG NODE_VERSION=24.13.0 ENV NVM_DIR=/home/frappe/.nvm ENV PATH=${NVM_DIR}/versions/node/v${NODE_VERSION}/bin/:${PATH} @@ -24,6 +22,8 @@ RUN useradd -ms /bin/bash frappe \ libharfbuzz0b \ libpangoft2-1.0-0 \ libpangocairo-1.0-0 \ + #Chromium + chromium-headless-shell \ # For backups restic \ gpg \ @@ -58,11 +58,6 @@ RUN useradd -ms /bin/bash frappe \ && curl -sLO https://github.com/wkhtmltopdf/packaging/releases/download/$WKHTMLTOPDF_VERSION/$downloaded_file \ && apt-get install -y ./$downloaded_file \ && rm $downloaded_file \ - # Chromium - && if [ "$INSTALL_CHROMIUM" = "true" ]; then \ - DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \ - chromium-headless-shell; \ - fi \ # Clean up && rm -rf /var/lib/apt/lists/* \ && rm -fr /etc/nginx/sites-enabled/default \ From c363f459a46d4d1834027edf33f3092991db431a Mon Sep 17 00:00:00 2001 From: Ingo Schuck Date: Fri, 8 May 2026 16:38:52 +0200 Subject: [PATCH 257/279] Reapply "feat(images): toggle chromium installation" This reverts commit 09fcd3e83b6327d27afd174d23ec116917adf000. --- docs/02-setup/02-build-setup.md | 1 + images/bench/Dockerfile | 8 ++++++-- images/custom/Containerfile | 9 +++++++-- images/production/Containerfile | 9 +++++++-- 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/docs/02-setup/02-build-setup.md b/docs/02-setup/02-build-setup.md index 326de9bf..09cef899 100644 --- a/docs/02-setup/02-build-setup.md +++ b/docs/02-setup/02-build-setup.md @@ -96,6 +96,7 @@ See [Automated Builds and Deployment](../03-production/06-automated-builds-and-d | PYTHON_VERSION | Python version for the base image | | NODE_VERSION | Node.js version | | WKHTMLTOPDF_VERSION | wkhtmltopdf version | +| INSTALL_CHROMIUM | Configure chromium installation, defaults to `true` - needed for Frappe Workbench version >15 | | **bench only** | | | DEBIAN_BASE | Debian base version for the bench image, defaults to `bookworm` | | WKHTMLTOPDF_DISTRO | use the specified distro for debian package. Default is `bookworm` | diff --git a/images/bench/Dockerfile b/images/bench/Dockerfile index 9c21345d..1cb0b278 100644 --- a/images/bench/Dockerfile +++ b/images/bench/Dockerfile @@ -4,6 +4,7 @@ LABEL author=frappΓ© ARG GIT_REPO=https://github.com/frappe/bench.git ARG GIT_BRANCH=v5.x +ARG INSTALL_CHROMIUM=true RUN apt-get update \ && DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \ @@ -23,8 +24,6 @@ RUN apt-get update \ libharfbuzz0b \ libpangoft2-1.0-0 \ libpangocairo-1.0-0 \ - #Chromium - chromium-headless-shell \ # to work inside the container locales \ build-essential \ @@ -75,6 +74,11 @@ RUN apt-get update \ file \ # For MIME type detection media-types \ + # Chromium + && if [ "$INSTALL_CHROMIUM" = "true" ]; then \ + DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \ + chromium-headless-shell; \ + fi \ && rm -rf /var/lib/apt/lists/* RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen \ diff --git a/images/custom/Containerfile b/images/custom/Containerfile index 2ecb06d7..5f8072f6 100644 --- a/images/custom/Containerfile +++ b/images/custom/Containerfile @@ -8,6 +8,8 @@ COPY resources/core/nginx/security_headers.conf /etc/nginx/snippets/security_hea ARG WKHTMLTOPDF_VERSION=0.12.6.1-3 ARG WKHTMLTOPDF_DISTRO=bookworm +ARG INSTALL_CHROMIUM=true + ARG NODE_VERSION=24.13.0 ENV NVM_DIR=/home/frappe/.nvm ENV PATH=${NVM_DIR}/versions/node/v${NODE_VERSION}/bin/:${PATH} @@ -26,8 +28,6 @@ RUN useradd -ms /bin/bash frappe \ libharfbuzz0b \ libpangoft2-1.0-0 \ libpangocairo-1.0-0 \ - #Chromium - chromium-headless-shell \ # For backups restic \ gpg \ @@ -62,6 +62,11 @@ RUN useradd -ms /bin/bash frappe \ && curl -sLO https://github.com/wkhtmltopdf/packaging/releases/download/$WKHTMLTOPDF_VERSION/$downloaded_file \ && apt-get install -y ./$downloaded_file \ && rm $downloaded_file \ + # Chromium + && if [ "$INSTALL_CHROMIUM" = "true" ]; then \ + DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \ + chromium-headless-shell; \ + fi \ # Clean up && rm -rf /var/lib/apt/lists/* \ && rm -fr /etc/nginx/sites-enabled/default \ diff --git a/images/production/Containerfile b/images/production/Containerfile index f95a9703..e2a2f3ee 100644 --- a/images/production/Containerfile +++ b/images/production/Containerfile @@ -4,6 +4,8 @@ FROM python:${PYTHON_VERSION}-slim-${DEBIAN_BASE} AS base ARG WKHTMLTOPDF_VERSION=0.12.6.1-3 ARG WKHTMLTOPDF_DISTRO=bookworm +ARG INSTALL_CHROMIUM=true + ARG NODE_VERSION=24.13.0 ENV NVM_DIR=/home/frappe/.nvm ENV PATH=${NVM_DIR}/versions/node/v${NODE_VERSION}/bin/:${PATH} @@ -22,8 +24,6 @@ RUN useradd -ms /bin/bash frappe \ libharfbuzz0b \ libpangoft2-1.0-0 \ libpangocairo-1.0-0 \ - #Chromium - chromium-headless-shell \ # For backups restic \ gpg \ @@ -58,6 +58,11 @@ RUN useradd -ms /bin/bash frappe \ && curl -sLO https://github.com/wkhtmltopdf/packaging/releases/download/$WKHTMLTOPDF_VERSION/$downloaded_file \ && apt-get install -y ./$downloaded_file \ && rm $downloaded_file \ + # Chromium + && if [ "$INSTALL_CHROMIUM" = "true" ]; then \ + DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \ + chromium-headless-shell; \ + fi \ # Clean up && rm -rf /var/lib/apt/lists/* \ && rm -fr /etc/nginx/sites-enabled/default \ From 37e91a2db231b9f76864295928eda9ce0313389d Mon Sep 17 00:00:00 2001 From: Ingo Schuck Date: Fri, 8 May 2026 16:39:31 +0200 Subject: [PATCH 258/279] Reapply "feat(images): permissive boolean check for INSTALL_CHROMIUM" This reverts commit 8f4130b5d33d015bbdf6aab50d6a6210e4084862. --- images/bench/Dockerfile | 2 +- images/custom/Containerfile | 2 +- images/production/Containerfile | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/images/bench/Dockerfile b/images/bench/Dockerfile index 1cb0b278..2b2540b5 100644 --- a/images/bench/Dockerfile +++ b/images/bench/Dockerfile @@ -75,7 +75,7 @@ RUN apt-get update \ # For MIME type detection media-types \ # Chromium - && if [ "$INSTALL_CHROMIUM" = "true" ]; then \ + && if [ "$INSTALL_CHROMIUM" != "false" ]; then \ DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \ chromium-headless-shell; \ fi \ diff --git a/images/custom/Containerfile b/images/custom/Containerfile index 5f8072f6..084104b3 100644 --- a/images/custom/Containerfile +++ b/images/custom/Containerfile @@ -63,7 +63,7 @@ RUN useradd -ms /bin/bash frappe \ && apt-get install -y ./$downloaded_file \ && rm $downloaded_file \ # Chromium - && if [ "$INSTALL_CHROMIUM" = "true" ]; then \ + && if [ "$INSTALL_CHROMIUM" != "false" ]; then \ DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \ chromium-headless-shell; \ fi \ diff --git a/images/production/Containerfile b/images/production/Containerfile index e2a2f3ee..983dc2ea 100644 --- a/images/production/Containerfile +++ b/images/production/Containerfile @@ -59,7 +59,7 @@ RUN useradd -ms /bin/bash frappe \ && apt-get install -y ./$downloaded_file \ && rm $downloaded_file \ # Chromium - && if [ "$INSTALL_CHROMIUM" = "true" ]; then \ + && if [ "$INSTALL_CHROMIUM" != "false" ]; then \ DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \ chromium-headless-shell; \ fi \ From 004b27a5a7f144c1974544978a4d08c8d7d14629 Mon Sep 17 00:00:00 2001 From: Ingo Schuck Date: Fri, 8 May 2026 16:41:30 +0200 Subject: [PATCH 259/279] Reapply "fix all entrypoint.sh permissions to 755" This reverts commit 93ade44c6b5f25b409c41f04c18e22737e74d69b. --- images/custom/Containerfile | 2 +- images/layered/Containerfile | 2 +- images/production/Containerfile | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/images/custom/Containerfile b/images/custom/Containerfile index 084104b3..9528688b 100644 --- a/images/custom/Containerfile +++ b/images/custom/Containerfile @@ -163,7 +163,7 @@ VOLUME [ \ USER root # This entrypoint script link build assets of the image to the mounted sites volume at container initialization COPY resources/core/main-entrypoint.sh /usr/local/bin/entrypoint.sh -RUN chmod +x /usr/local/bin/entrypoint.sh +RUN chmod 755 /usr/local/bin/entrypoint.sh USER frappe ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] diff --git a/images/layered/Containerfile b/images/layered/Containerfile index 18511c61..c3326ddd 100644 --- a/images/layered/Containerfile +++ b/images/layered/Containerfile @@ -47,7 +47,7 @@ VOLUME [ \ USER root # This entrypoint script link build assets of the image to the mounted sites volume at container initialization COPY resources/core/main-entrypoint.sh /usr/local/bin/entrypoint.sh -RUN chmod ugo+rx /usr/local/bin/entrypoint.sh +RUN chmod 755 /usr/local/bin/entrypoint.sh USER frappe ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] diff --git a/images/production/Containerfile b/images/production/Containerfile index 983dc2ea..7ad4089d 100644 --- a/images/production/Containerfile +++ b/images/production/Containerfile @@ -82,6 +82,7 @@ RUN useradd -ms /bin/bash frappe \ COPY resources/core/nginx/nginx-template.conf /templates/nginx/frappe.conf.template COPY resources/core/nginx/nginx-entrypoint.sh /usr/local/bin/nginx-entrypoint.sh COPY resources/core/nginx/security_headers.conf /etc/nginx/snippets/security_headers.conf +RUN chmod 755 /usr/local/bin/nginx-entrypoint.sh FROM base AS build @@ -153,7 +154,7 @@ VOLUME [ \ USER root # This entrypoint script link build assets of the image to the mounted sites volume at container initialization COPY resources/core/main-entrypoint.sh /usr/local/bin/entrypoint.sh -RUN chmod +x /usr/local/bin/entrypoint.sh +RUN chmod 755 /usr/local/bin/entrypoint.sh USER frappe ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] From d07d805436e4b55ead896c7931902abc084e028a Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 12 May 2026 19:20:13 +0000 Subject: [PATCH 260/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 899486dd..eadd9b77 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/02-setup/04-env-variables.md -ERPNEXT_VERSION=v16.17.0 +ERPNEXT_VERSION=v16.18.0 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index 6997042d..bcef3e1d 100644 --- a/pwd.yml +++ b/pwd.yml @@ -1,6 +1,6 @@ services: backend: - image: frappe/erpnext:v16.17.0 + image: frappe/erpnext:v16.18.0 networks: - frappe_network deploy: @@ -16,7 +16,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v16.17.0 + image: frappe/erpnext:v16.18.0 networks: - frappe_network deploy: @@ -45,7 +45,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v16.17.0 + image: frappe/erpnext:v16.18.0 networks: - frappe_network deploy: @@ -101,7 +101,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v16.17.0 + image: frappe/erpnext:v16.18.0 networks: - frappe_network depends_on: @@ -127,7 +127,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v16.17.0 + image: frappe/erpnext:v16.18.0 networks: - frappe_network deploy: @@ -146,7 +146,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v16.17.0 + image: frappe/erpnext:v16.18.0 networks: - frappe_network deploy: @@ -183,7 +183,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v16.17.0 + image: frappe/erpnext:v16.18.0 networks: - frappe_network deploy: @@ -197,7 +197,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v16.17.0 + image: frappe/erpnext:v16.18.0 networks: - frappe_network deploy: From cec5b935460eb09a85fb3c32cba798a6fcf88845 Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 13 May 2026 10:46:13 +0000 Subject: [PATCH 261/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index eadd9b77..72ab12cf 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/02-setup/04-env-variables.md -ERPNEXT_VERSION=v16.18.0 +ERPNEXT_VERSION=v16.18.1 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index bcef3e1d..c0385d04 100644 --- a/pwd.yml +++ b/pwd.yml @@ -1,6 +1,6 @@ services: backend: - image: frappe/erpnext:v16.18.0 + image: frappe/erpnext:v16.18.1 networks: - frappe_network deploy: @@ -16,7 +16,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v16.18.0 + image: frappe/erpnext:v16.18.1 networks: - frappe_network deploy: @@ -45,7 +45,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v16.18.0 + image: frappe/erpnext:v16.18.1 networks: - frappe_network deploy: @@ -101,7 +101,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v16.18.0 + image: frappe/erpnext:v16.18.1 networks: - frappe_network depends_on: @@ -127,7 +127,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v16.18.0 + image: frappe/erpnext:v16.18.1 networks: - frappe_network deploy: @@ -146,7 +146,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v16.18.0 + image: frappe/erpnext:v16.18.1 networks: - frappe_network deploy: @@ -183,7 +183,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v16.18.0 + image: frappe/erpnext:v16.18.1 networks: - frappe_network deploy: @@ -197,7 +197,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v16.18.0 + image: frappe/erpnext:v16.18.1 networks: - frappe_network deploy: From eeb487e5e62f1b2d9314849a53796727dbd8e788 Mon Sep 17 00:00:00 2001 From: github-actions Date: Thu, 14 May 2026 06:04:47 +0000 Subject: [PATCH 262/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 72ab12cf..f9662581 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/02-setup/04-env-variables.md -ERPNEXT_VERSION=v16.18.1 +ERPNEXT_VERSION=v16.18.2 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index c0385d04..0c478ceb 100644 --- a/pwd.yml +++ b/pwd.yml @@ -1,6 +1,6 @@ services: backend: - image: frappe/erpnext:v16.18.1 + image: frappe/erpnext:v16.18.2 networks: - frappe_network deploy: @@ -16,7 +16,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v16.18.1 + image: frappe/erpnext:v16.18.2 networks: - frappe_network deploy: @@ -45,7 +45,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v16.18.1 + image: frappe/erpnext:v16.18.2 networks: - frappe_network deploy: @@ -101,7 +101,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v16.18.1 + image: frappe/erpnext:v16.18.2 networks: - frappe_network depends_on: @@ -127,7 +127,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v16.18.1 + image: frappe/erpnext:v16.18.2 networks: - frappe_network deploy: @@ -146,7 +146,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v16.18.1 + image: frappe/erpnext:v16.18.2 networks: - frappe_network deploy: @@ -183,7 +183,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v16.18.1 + image: frappe/erpnext:v16.18.2 networks: - frappe_network deploy: @@ -197,7 +197,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v16.18.1 + image: frappe/erpnext:v16.18.2 networks: - frappe_network deploy: From e31bcceac171f5b5823130a3524fb1f7796c61f3 Mon Sep 17 00:00:00 2001 From: github-actions Date: Thu, 14 May 2026 10:07:39 +0000 Subject: [PATCH 263/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index f9662581..a8db8d79 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/02-setup/04-env-variables.md -ERPNEXT_VERSION=v16.18.2 +ERPNEXT_VERSION=v16.18.3 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index 0c478ceb..5479dba6 100644 --- a/pwd.yml +++ b/pwd.yml @@ -1,6 +1,6 @@ services: backend: - image: frappe/erpnext:v16.18.2 + image: frappe/erpnext:v16.18.3 networks: - frappe_network deploy: @@ -16,7 +16,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v16.18.2 + image: frappe/erpnext:v16.18.3 networks: - frappe_network deploy: @@ -45,7 +45,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v16.18.2 + image: frappe/erpnext:v16.18.3 networks: - frappe_network deploy: @@ -101,7 +101,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v16.18.2 + image: frappe/erpnext:v16.18.3 networks: - frappe_network depends_on: @@ -127,7 +127,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v16.18.2 + image: frappe/erpnext:v16.18.3 networks: - frappe_network deploy: @@ -146,7 +146,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v16.18.2 + image: frappe/erpnext:v16.18.3 networks: - frappe_network deploy: @@ -183,7 +183,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v16.18.2 + image: frappe/erpnext:v16.18.3 networks: - frappe_network deploy: @@ -197,7 +197,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v16.18.2 + image: frappe/erpnext:v16.18.3 networks: - frappe_network deploy: From aafc25bc76339ea84e89c821d28fac458dc41c9c Mon Sep 17 00:00:00 2001 From: Harshith Ashok Date: Sun, 17 May 2026 07:45:04 +0530 Subject: [PATCH 264/279] docs(contributing): add docker dev guide --- README.md | 1 + docs/10-development/01-setup.md | 252 ++++++++++++++++++++++++++++++++ 2 files changed, 253 insertions(+) create mode 100644 docs/10-development/01-setup.md diff --git a/README.md b/README.md index 769efef7..ac8479a4 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,7 @@ The full `frappe_docker` documentation is available in [`docs/`](docs/) and publ - **Running in production:** [Production docs](docs/03-production/) - **Operating a deployment:** [Operations docs](docs/04-operations/) - **Development workflows:** [Development](docs/05-development/01-development.md) +- **Docker Container Setup for Development** [Docker Setup](docs/10-development/01-setup.md) - **FAQ:** [Frequently Asked Questions](https://github.com/frappe/frappe_docker/wiki/Frequently-Asked-Questions) ## Prerequisites diff --git a/docs/10-development/01-setup.md b/docs/10-development/01-setup.md new file mode 100644 index 00000000..3577acb3 --- /dev/null +++ b/docs/10-development/01-setup.md @@ -0,0 +1,252 @@ +--- +title: Docker Development Setup +--- + +# Docker Development Setup + +A complete guide for setting up a Frappe development environment on x86 and ARM based computers running UNIX based OSes by running containers directly and working inside them via the terminal. No VS Code Dev Containers extension needed. + +--- + +## Prerequisites + +- **Docker Desktop** (Applicable only for MacOS) β€” [download here](https://www.docker.com/products/docker-desktop/) +- **Git** +- A terminal (iTerm2, or the built-in Terminal.app) + +### Docker Desktop Resource Allocation (Critical) + +1. Open Docker Desktop β†’ **Settings** β†’ **Resources** +2. **Memory**: at least **6 GB** (8 GB recommended) +3. **CPUs**: at least **4** +4. **Disk image size**: at least **60 GB** +5. Click **Apply & Restart** + +--- + +## Step 1 β€” Set ARM64 as Default Platform (ONLY FOR ARM BASED SYSTEMS) + +```bash +export DOCKER_DEFAULT_PLATFORM=linux/arm64 +``` + +Make it permanent: + +```bash +echo 'export DOCKER_DEFAULT_PLATFORM=linux/arm64' >> ~/.zshrc +source ~/.zshrc +``` + +--- + +## Step 2 β€” Clone the Repo + +```bash +git clone https://github.com/frappe/frappe_docker.git +cd frappe_docker +``` + +--- + +## Step 3 β€” Set Up the Dev Container Config + +The `devcontainer-example/` folder contains a ready-made `docker-compose.yml` for development. Copy it into place: + +```bash +cp -R devcontainer-example .devcontainer +``` + +This gives you `.devcontainer/docker-compose.yml` which defines all the services you need: + +- `frappe` β€” the main development container (Debian, Python, Node, bench) +- `mariadb` β€” the database +- `redis-cache` β€” cache layer +- `redis-queue` β€” background job queue + +--- + +## Step 4 β€” Add ARM64 Platform to All Services + +Open `.devcontainer/docker-compose.yml` in any editor and add `platform: linux/arm64` to every service block. It should look like this: + +```yaml +services: + frappe: + image: frappe/bench:latest + platform: linux/arm64 + # ... rest of config + + mariadb: + image: mariadb:10.8 + platform: linux/arm64 + # ... + + redis-cache: + image: redis:6.2-alpine + platform: linux/arm64 + # ... + + redis-queue: + image: redis:6.2-alpine + platform: linux/arm64 + # ... +``` + +> Without this, Docker may pull amd64 images and emulate them via Rosetta β€” things will work but be noticeably slower. +> Ensure mariadb version is set to `10.8` since Frappe Framework is not yet tested for the default version `11.8` + +--- + +## Step 5 β€” Start the Containers + +```bash +docker compose -f .devcontainer/docker-compose.yml up -d +``` + +Verify everything is running: + +```bash +docker compose -f .devcontainer/docker-compose.yml ps +``` + +You should see all services with status `Up`. + +In case you get any errors along the lines of, + +```log +Error response from daemon: failed to set up container networking: driver failed programming external connectivity on endpoint devcontainer-frappe-1 (44b337b68d100e914fab0ce446ed08d791cc73aaffb05cf47c347c00ff88f567): Bind for 0.0.0.0:9001 failed: port is already allocated +``` + +- Check if the port is being used by another service with `lsof -i :PORT` + > Usually on MacOS ports 8000 and 9000 are usually reserved for system use +- Go to line 60 and 61 under the `frappe` service and change the ports + +Eg: + +``` +ports: + - 8001-8005:8001-8005 + - 9002-9005:9002-9005 +``` + +--- + +## Step 6 β€” Enter the Development Container + +```bash +docker exec -e "TERM=xterm-256color" -w /workspace/development -it devcontainer-frappe-1 bash +``` + +> The container name is typically `devcontainer-frappe-1`. If it differs, check with `docker ps` and use the actual name shown. + +You are now inside the container as the `frappe` user. All subsequent commands in this guide run **inside the container** unless noted otherwise. + +--- + +## Step 7 β€” Initialize a Bench + +```bash +bench init --skip-redis-config-generation --frappe-branch version-16 frappe-bench +cd frappe-bench +``` + +Use `version-16` for the latest stable release. Swap for `version-15` if needed. + +This creates: + +``` +development/ +└── frappe-bench/ + β”œβ”€β”€ apps/ ← All Frappe apps live here + β”œβ”€β”€ sites/ ← Your sites (databases, uploaded files) + β”œβ”€β”€ env/ ← Python virtualenv + β”œβ”€β”€ logs/ + └── Procfile +``` + +--- + +## Step 8 β€” Configure Service Hosts + +Tell bench to use the containerised services (not localhost): + +```bash +bench set-config -g db_host mariadb +bench set-config -g redis_cache redis://redis-cache:6379 +bench set-config -g redis_queue redis://redis-queue:6379 +bench set-config -g redis_socketio redis://redis-queue:6379 +``` + +If any command fails, edit the file directly: + +```bash +nano sites/common_site_config.json +``` + +Paste: + +```json +{ + "db_host": "mariadb", + "redis_cache": "redis://redis-cache:6379", + "redis_queue": "redis://redis-queue:6379", + "redis_socketio": "redis://redis-queue:6379" +} +``` + +--- + +## Step 9 β€” Fix the Procfile + +Redis runs in separate containers, so remove it from Honcho's Procfile to avoid conflicts: + +```bash +sudo sed -i '/redis/d' ./Procfile +``` + +--- + +## Step 10 β€” Create a Site + +```bash +bench new-site \ + --db-root-password 123 \ + --admin-password admin \ + --mariadb-user-host-login-scope=% \ + development.localhost +``` + +- MariaDB root password: `123` (set in the docker-compose defaults) +- Admin password: `admin` (change this to whatever you want) +- Site name **must end in `.localhost`** + +--- + +## Step 11 β€” Enable Developer Mode + +```bash +bench --site development.localhost set-config developer_mode 1 +bench --site development.localhost clear-cache +``` + +--- + +## Step 12 β€” Add development.localhost to /etc/hosts (on your Mac) + +Run this **on your Mac** (not inside the container): + +```bash +echo "127.0.0.1 development.localhost" | sudo tee -a /etc/hosts +``` + +--- + +## Step 13 β€” Start the Dev Server + +```bash +bench build # (optional) +bench start +``` + +Open your browser at **http://development.localhost:8000** +Login: `Administrator` / `admin` From cfd280eff3aac9cc2403e2baab0d117f4575de92 Mon Sep 17 00:00:00 2001 From: Harshith Ashok <50227707+harshith-ashok@users.noreply.github.com> Date: Sun, 17 May 2026 09:21:54 +0530 Subject: [PATCH 265/279] Clarify mariadb version requirement in setup Add note about mariadb version for Frappe Framework. --- docs/10-development/01-setup.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/10-development/01-setup.md b/docs/10-development/01-setup.md index 3577acb3..485e7387 100644 --- a/docs/10-development/01-setup.md +++ b/docs/10-development/01-setup.md @@ -93,8 +93,7 @@ services: ``` > Without this, Docker may pull amd64 images and emulate them via Rosetta β€” things will work but be noticeably slower. -> Ensure mariadb version is set to `10.8` since Frappe Framework is not yet tested for the default version `11.8` - +> --- ## Step 5 β€” Start the Containers From 5097115d08db19511c829beeb47517022dd72546 Mon Sep 17 00:00:00 2001 From: Harshith Ashok <50227707+harshith-ashok@users.noreply.github.com> Date: Sun, 17 May 2026 09:26:23 +0530 Subject: [PATCH 266/279] Update setup.md with mariadb version change advice Added note about mariadb version causing errors. This addition is based on Issue #1908 which I too faced while testing and setting it up myself. --- docs/10-development/01-setup.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/10-development/01-setup.md b/docs/10-development/01-setup.md index 485e7387..567cb558 100644 --- a/docs/10-development/01-setup.md +++ b/docs/10-development/01-setup.md @@ -93,7 +93,8 @@ services: ``` > Without this, Docker may pull amd64 images and emulate them via Rosetta β€” things will work but be noticeably slower. -> +> Few users did note that the version of mariadb causes an error while creating a new site so in case you do encouter it change the version from `11.8` to `10.8` + --- ## Step 5 β€” Start the Containers From 2c44349a0f16ae97bf45053b61ea5851352444d1 Mon Sep 17 00:00:00 2001 From: dandax123 Date: Mon, 27 Apr 2026 17:39:45 +0200 Subject: [PATCH 267/279] feat: configure gunicorn with env variables --- compose.yaml | 4 ++++ docs/02-setup/04-env-variables.md | 10 ++++++++++ example.env | 11 +++++++++++ images/custom/Containerfile | 16 ++++------------ images/layered/Containerfile | 16 ++++------------ images/production/Containerfile | 16 ++++------------ resources/core/start.sh | 20 ++++++++++++++++++++ 7 files changed, 57 insertions(+), 36 deletions(-) create mode 100755 resources/core/start.sh diff --git a/compose.yaml b/compose.yaml index 5920e6d3..d69e4d19 100644 --- a/compose.yaml +++ b/compose.yaml @@ -46,6 +46,10 @@ services: backend: <<: *backend_defaults platform: linux/amd64 + environment: + GUNICORN_THREADS: ${GUNICORN_THREADS:-4} + GUNICORN_WORKERS: ${GUNICORN_WORKERS:-2} + GUNICORN_TIMEOUT: ${GUNICORN_TIMEOUT:-120} frontend: <<: *customizable_image diff --git a/docs/02-setup/04-env-variables.md b/docs/02-setup/04-env-variables.md index 561ee6d2..069e3231 100644 --- a/docs/02-setup/04-env-variables.md +++ b/docs/02-setup/04-env-variables.md @@ -122,6 +122,16 @@ If your site is named `example.com` and you access it via that domain, no need t --- +## Backend (Gunicorn) Configuration + +| Variable | Purpose | Default | When to Set / Allowed Values | +| :----------------- | :------------------------------------------------------------- | :------ | :------------------------------------------------------------------------------- | +| `GUNICORN_WORKERS` | Number of worker processes handling web requests | `2` | Scale up for multi-core CPUs. Formula: `(2 x Cores) + 1` | +| `GUNICORN_THREADS` | Number of concurrent threads per worker process | `4` | Increase to handle more simultaneous I/O-bound requests without high memory cost | +| `GUNICORN_TIMEOUT` | Max time a worker can spend on a single request before restart | `120` | Increase if long-running reports or data imports time out | + +--- + ## Frontend Nginx Configuration (inside the frontend container) | Variable | Purpose | Default | Allowed Values | diff --git a/example.env b/example.env index a8db8d79..893c21e3 100644 --- a/example.env +++ b/example.env @@ -15,6 +15,17 @@ DB_PORT= REDIS_CACHE= REDIS_QUEUE= + +# The number of threads per Gunicorn worker process for handling concurrent requests. +GUNICORN_THREADS=4 + +# The number of worker processes for handling requests. +# A typical formula is (2 x number of CPU cores) + 1. +GUNICORN_WORKERS=2 + +# Workers exceeding this timeout (in seconds) will be killed and restarted. +GUNICORN_TIMEOUT=120 + # Only with HTTPS override LETSENCRYPT_EMAIL=mail@example.com diff --git a/images/custom/Containerfile b/images/custom/Containerfile index 9528688b..70e4317b 100644 --- a/images/custom/Containerfile +++ b/images/custom/Containerfile @@ -165,18 +165,10 @@ USER root COPY resources/core/main-entrypoint.sh /usr/local/bin/entrypoint.sh RUN chmod 755 /usr/local/bin/entrypoint.sh +COPY resources/core/start.sh /usr/local/bin/start.sh +RUN chmod 755 /usr/local/bin/start.sh + USER frappe ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] -CMD [ \ - "/home/frappe/frappe-bench/env/bin/gunicorn", \ - "--chdir=/home/frappe/frappe-bench/sites", \ - "--bind=0.0.0.0:8000", \ - "--threads=4", \ - "--workers=2", \ - "--worker-class=gthread", \ - "--worker-tmp-dir=/dev/shm", \ - "--timeout=120", \ - "--preload", \ - "frappe.app:application" \ -] +CMD ["start.sh"] diff --git a/images/layered/Containerfile b/images/layered/Containerfile index c3326ddd..ec32cbdb 100644 --- a/images/layered/Containerfile +++ b/images/layered/Containerfile @@ -49,18 +49,10 @@ USER root COPY resources/core/main-entrypoint.sh /usr/local/bin/entrypoint.sh RUN chmod 755 /usr/local/bin/entrypoint.sh +COPY resources/core/start.sh /usr/local/bin/start.sh +RUN chmod 755 /usr/local/bin/start.sh + USER frappe ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] -CMD [ \ - "/home/frappe/frappe-bench/env/bin/gunicorn", \ - "--chdir=/home/frappe/frappe-bench/sites", \ - "--bind=0.0.0.0:8000", \ - "--threads=4", \ - "--workers=2", \ - "--worker-class=gthread", \ - "--worker-tmp-dir=/dev/shm", \ - "--timeout=120", \ - "--preload", \ - "frappe.app:application" \ -] +CMD ["start.sh"] diff --git a/images/production/Containerfile b/images/production/Containerfile index 7ad4089d..b30dd957 100644 --- a/images/production/Containerfile +++ b/images/production/Containerfile @@ -156,18 +156,10 @@ USER root COPY resources/core/main-entrypoint.sh /usr/local/bin/entrypoint.sh RUN chmod 755 /usr/local/bin/entrypoint.sh +COPY resources/core/start.sh /usr/local/bin/start.sh +RUN chmod 755 /usr/local/bin/start.sh + USER frappe ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] -CMD [ \ - "/home/frappe/frappe-bench/env/bin/gunicorn", \ - "--chdir=/home/frappe/frappe-bench/sites", \ - "--bind=0.0.0.0:8000", \ - "--threads=4", \ - "--workers=2", \ - "--worker-class=gthread", \ - "--worker-tmp-dir=/dev/shm", \ - "--timeout=120", \ - "--preload", \ - "frappe.app:application" \ -] +CMD ["start.sh"] diff --git a/resources/core/start.sh b/resources/core/start.sh new file mode 100755 index 00000000..2ac1a388 --- /dev/null +++ b/resources/core/start.sh @@ -0,0 +1,20 @@ +#!/bin/bash +set -e + +#Gunicorn defaults +GUNICORN_THREADS=${GUNICORN_THREADS:-4} +GUNICORN_WORKERS=${GUNICORN_WORKERS:-2} +GUNICORN_TIMEOUT=${GUNICORN_TIMEOUT:-120} + +echo "Booting Gunicorn with $GUNICORN_WORKERS workers and $GUNICORN_THREADS threads..." + +exec /home/frappe/frappe-bench/env/bin/gunicorn \ + --chdir=/home/frappe/frappe-bench/sites \ + --bind=0.0.0.0:8000 \ + --threads="$GUNICORN_THREADS" \ + --workers="$GUNICORN_WORKERS" \ + --worker-class=gthread \ + --worker-tmp-dir=/dev/shm \ + --timeout="$GUNICORN_TIMEOUT" \ + --preload \ + frappe.app:application From 6e1117bbbc2cdc900df4a855321f67e96bd712cb Mon Sep 17 00:00:00 2001 From: Harshith Ashok Date: Tue, 19 May 2026 00:22:22 +0530 Subject: [PATCH 268/279] removed old file and replaced it under development --- README.md | 1 - .../01-setup.md => 05-development/04-alternate-setup.md} | 5 ++++- 2 files changed, 4 insertions(+), 2 deletions(-) rename docs/{10-development/01-setup.md => 05-development/04-alternate-setup.md} (95%) diff --git a/README.md b/README.md index ac8479a4..769efef7 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,6 @@ The full `frappe_docker` documentation is available in [`docs/`](docs/) and publ - **Running in production:** [Production docs](docs/03-production/) - **Operating a deployment:** [Operations docs](docs/04-operations/) - **Development workflows:** [Development](docs/05-development/01-development.md) -- **Docker Container Setup for Development** [Docker Setup](docs/10-development/01-setup.md) - **FAQ:** [Frequently Asked Questions](https://github.com/frappe/frappe_docker/wiki/Frequently-Asked-Questions) ## Prerequisites diff --git a/docs/10-development/01-setup.md b/docs/05-development/04-alternate-setup.md similarity index 95% rename from docs/10-development/01-setup.md rename to docs/05-development/04-alternate-setup.md index 567cb558..29de8669 100644 --- a/docs/10-development/01-setup.md +++ b/docs/05-development/04-alternate-setup.md @@ -6,6 +6,9 @@ title: Docker Development Setup A complete guide for setting up a Frappe development environment on x86 and ARM based computers running UNIX based OSes by running containers directly and working inside them via the terminal. No VS Code Dev Containers extension needed. +> [!IMPORTANT] +> Devcontainers are the intended development setup for Frappe Framework but in case you don't want to use that method follow these instructions to use the CLI directly instead + --- ## Prerequisites @@ -93,7 +96,7 @@ services: ``` > Without this, Docker may pull amd64 images and emulate them via Rosetta β€” things will work but be noticeably slower. -> Few users did note that the version of mariadb causes an error while creating a new site so in case you do encouter it change the version from `11.8` to `10.8` +> Ensure mariadb version is set to `10.8` since Frappe Framework is not yet tested for the default version `11.8` --- From 48764b21c18ede53c311ea1ec60a3ff4783466dc Mon Sep 17 00:00:00 2001 From: Harshith Ashok <50227707+harshith-ashok@users.noreply.github.com> Date: Tue, 19 May 2026 19:55:03 +0530 Subject: [PATCH 269/279] remove mariadb version for Frappe Framework setup --- docs/05-development/04-alternate-setup.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/05-development/04-alternate-setup.md b/docs/05-development/04-alternate-setup.md index 29de8669..d2027479 100644 --- a/docs/05-development/04-alternate-setup.md +++ b/docs/05-development/04-alternate-setup.md @@ -96,7 +96,6 @@ services: ``` > Without this, Docker may pull amd64 images and emulate them via Rosetta β€” things will work but be noticeably slower. -> Ensure mariadb version is set to `10.8` since Frappe Framework is not yet tested for the default version `11.8` --- From 38ca8d2316f68d9d2a5adc07f554d6316a8f7397 Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 20 May 2026 04:40:07 +0000 Subject: [PATCH 270/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 893c21e3..e5ea9d98 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/02-setup/04-env-variables.md -ERPNEXT_VERSION=v16.18.3 +ERPNEXT_VERSION=v16.19.0 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index 5479dba6..7fc750cb 100644 --- a/pwd.yml +++ b/pwd.yml @@ -1,6 +1,6 @@ services: backend: - image: frappe/erpnext:v16.18.3 + image: frappe/erpnext:v16.19.0 networks: - frappe_network deploy: @@ -16,7 +16,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v16.18.3 + image: frappe/erpnext:v16.19.0 networks: - frappe_network deploy: @@ -45,7 +45,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v16.18.3 + image: frappe/erpnext:v16.19.0 networks: - frappe_network deploy: @@ -101,7 +101,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v16.18.3 + image: frappe/erpnext:v16.19.0 networks: - frappe_network depends_on: @@ -127,7 +127,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v16.18.3 + image: frappe/erpnext:v16.19.0 networks: - frappe_network deploy: @@ -146,7 +146,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v16.18.3 + image: frappe/erpnext:v16.19.0 networks: - frappe_network deploy: @@ -183,7 +183,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v16.18.3 + image: frappe/erpnext:v16.19.0 networks: - frappe_network deploy: @@ -197,7 +197,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v16.18.3 + image: frappe/erpnext:v16.19.0 networks: - frappe_network deploy: From 640b761a3ddc6b46c049813b02a8e151f865ff29 Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 20 May 2026 07:50:29 +0000 Subject: [PATCH 271/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index e5ea9d98..3704b8f0 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/02-setup/04-env-variables.md -ERPNEXT_VERSION=v16.19.0 +ERPNEXT_VERSION=v16.19.1 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index 7fc750cb..1fcde0cc 100644 --- a/pwd.yml +++ b/pwd.yml @@ -1,6 +1,6 @@ services: backend: - image: frappe/erpnext:v16.19.0 + image: frappe/erpnext:v16.19.1 networks: - frappe_network deploy: @@ -16,7 +16,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v16.19.0 + image: frappe/erpnext:v16.19.1 networks: - frappe_network deploy: @@ -45,7 +45,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v16.19.0 + image: frappe/erpnext:v16.19.1 networks: - frappe_network deploy: @@ -101,7 +101,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v16.19.0 + image: frappe/erpnext:v16.19.1 networks: - frappe_network depends_on: @@ -127,7 +127,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v16.19.0 + image: frappe/erpnext:v16.19.1 networks: - frappe_network deploy: @@ -146,7 +146,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v16.19.0 + image: frappe/erpnext:v16.19.1 networks: - frappe_network deploy: @@ -183,7 +183,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v16.19.0 + image: frappe/erpnext:v16.19.1 networks: - frappe_network deploy: @@ -197,7 +197,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v16.19.0 + image: frappe/erpnext:v16.19.1 networks: - frappe_network deploy: From 33f24b2645214ff0d6320083ec69f873c5cd1ff5 Mon Sep 17 00:00:00 2001 From: Daniel Radl Date: Thu, 21 May 2026 14:54:46 +0200 Subject: [PATCH 272/279] feat(actions):add exept issue label --- .github/workflows/stale.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 8849bfea..fed39a73 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -16,3 +16,4 @@ jobs: stale-pr-message: This PR has been automatically marked as stale. You have a week to explain why you believe this is an error. stale-issue-label: no-issue-activity stale-pr-label: no-pr-activity + exempt-issue-labels: keep-open From 08d765c41394d22e22bf593752a03aab1f92ea5d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 21 May 2026 13:01:31 +0000 Subject: [PATCH 273/279] chore(deps): bump postcss from 8.5.8 to 8.5.15 in /docs Bumps [postcss](https://github.com/postcss/postcss) from 8.5.8 to 8.5.15. - [Release notes](https://github.com/postcss/postcss/releases) - [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md) - [Commits](https://github.com/postcss/postcss/compare/8.5.8...8.5.15) --- updated-dependencies: - dependency-name: postcss dependency-version: 8.5.15 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- docs/pnpm-lock.yaml | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/docs/pnpm-lock.yaml b/docs/pnpm-lock.yaml index 2e0b4ee7..c141e1e1 100644 --- a/docs/pnpm-lock.yaml +++ b/docs/pnpm-lock.yaml @@ -15,7 +15,7 @@ importers: devDependencies: vitepress: specifier: 2.0.0-alpha.16 - version: 2.0.0-alpha.16(postcss@8.5.8) + version: 2.0.0-alpha.16(postcss@8.5.15) vitepress-sidebar: specifier: 1.33.1 version: 1.33.1 @@ -408,6 +408,7 @@ packages: '@ungap/structured-clone@1.3.0': resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} + deprecated: Potential CWE-502 - Update to 1.3.1 or higher '@vitejs/plugin-vue@6.0.5': resolution: {integrity: sha512-bL3AxKuQySfk1iGcBsQnoRVexTPJq0Z/ixFVM8OhVJAP6ZXXXLtM7NFKWhLl30Kg7uTBqIaPXbh+nuQCuBDedg==} @@ -707,8 +708,8 @@ packages: minisearch@7.2.0: resolution: {integrity: sha512-dqT2XBYUOZOiC5t2HRnwADjhNS2cecp9u+TJRiJ1Qp/f5qjkeT5APcGPjHw+bz89Ms8Jp+cG4AlE+QZ/QnDglg==} - nanoid@3.3.11: - resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + nanoid@3.3.12: + resolution: {integrity: sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true @@ -739,8 +740,8 @@ packages: resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} engines: {node: '>=12'} - postcss@8.5.8: - resolution: {integrity: sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==} + postcss@8.5.15: + resolution: {integrity: sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==} engines: {node: ^10 || ^12 || >=14} property-information@7.1.0: @@ -1214,7 +1215,7 @@ snapshots: '@vue/shared': 3.5.30 estree-walker: 2.0.2 magic-string: 0.30.21 - postcss: 8.5.8 + postcss: 8.5.15 source-map-js: 1.2.1 '@vue/compiler-ssr@3.5.30': @@ -1491,7 +1492,7 @@ snapshots: minisearch@7.2.0: {} - nanoid@3.3.11: {} + nanoid@3.3.12: {} oniguruma-parser@0.12.1: {} @@ -1516,9 +1517,9 @@ snapshots: picomatch@4.0.4: {} - postcss@8.5.8: + postcss@8.5.15: dependencies: - nanoid: 3.3.11 + nanoid: 3.3.12 picocolors: 1.1.1 source-map-js: 1.2.1 @@ -1671,7 +1672,7 @@ snapshots: esbuild: 0.27.4 fdir: 6.5.0(picomatch@4.0.4) picomatch: 4.0.4 - postcss: 8.5.8 + postcss: 8.5.15 rollup: 4.59.0 tinyglobby: 0.2.15 optionalDependencies: @@ -1683,7 +1684,7 @@ snapshots: gray-matter: 4.0.3 qsu: 1.10.4 - vitepress@2.0.0-alpha.16(postcss@8.5.8): + vitepress@2.0.0-alpha.16(postcss@8.5.15): dependencies: '@docsearch/css': 4.6.0 '@docsearch/js': 4.6.0 @@ -1705,7 +1706,7 @@ snapshots: vite: 7.3.2 vue: 3.5.30 optionalDependencies: - postcss: 8.5.8 + postcss: 8.5.15 transitivePeerDependencies: - '@types/node' - async-validator From 0cb8df1631a41bdaa99d1ae5e8867bbeda35781c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 May 2026 08:36:36 +0000 Subject: [PATCH 274/279] chore(deps): bump docker/bake-action from 7.1.0 to 7.2.0 Bumps [docker/bake-action](https://github.com/docker/bake-action) from 7.1.0 to 7.2.0. - [Release notes](https://github.com/docker/bake-action/releases) - [Commits](https://github.com/docker/bake-action/compare/v7.1.0...v7.2.0) --- updated-dependencies: - dependency-name: docker/bake-action dependency-version: 7.2.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/core-build-bench.yml | 4 ++-- .github/workflows/core-build-test-images.yml | 2 +- .github/workflows/core-publish-images.yml | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/core-build-bench.yml b/.github/workflows/core-build-bench.yml index ef0ecbd0..0f6d08e9 100644 --- a/.github/workflows/core-build-bench.yml +++ b/.github/workflows/core-build-bench.yml @@ -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@v7.1.0 + uses: docker/bake-action@v7.2.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@v7.1.0 + uses: docker/bake-action@v7.2.0 with: targets: bench push: true diff --git a/.github/workflows/core-build-test-images.yml b/.github/workflows/core-build-test-images.yml index 7c118c93..ad09d479 100644 --- a/.github/workflows/core-build-test-images.yml +++ b/.github/workflows/core-build-test-images.yml @@ -87,7 +87,7 @@ jobs: echo "NODE_VERSION=${{ inputs.node_version }}" >> "$GITHUB_ENV" - name: Build - uses: docker/bake-action@v7.1.0 + uses: docker/bake-action@v7.2.0 with: source: . push: true diff --git a/.github/workflows/core-publish-images.yml b/.github/workflows/core-publish-images.yml index 4da6bfee..e8e975d1 100644 --- a/.github/workflows/core-publish-images.yml +++ b/.github/workflows/core-publish-images.yml @@ -70,7 +70,7 @@ jobs: password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Push Docker Hub images - uses: docker/bake-action@v7.1.0 + uses: docker/bake-action@v7.2.0 with: push: true set: "*.platform=linux/amd64,linux/arm64" @@ -83,7 +83,7 @@ jobs: password: ${{ secrets.GITHUB_TOKEN }} - name: Push GHCR base images - uses: docker/bake-action@v7.1.0 + uses: docker/bake-action@v7.2.0 with: targets: base-images push: true From cb0eda521440537d102e7ffdb873046eaad23713 Mon Sep 17 00:00:00 2001 From: Frederic Ollivier Date: Sat, 23 May 2026 16:46:29 +0200 Subject: [PATCH 275/279] Change ERPNext version to v16.19.1 Fix typo in platform, arm64 instead of amd64 --- docs/01-getting-started/03-arm64.md | 38 ++++++++++++++--------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/docs/01-getting-started/03-arm64.md b/docs/01-getting-started/03-arm64.md index b9defd89..1fe06165 100644 --- a/docs/01-getting-started/03-arm64.md +++ b/docs/01-getting-started/03-arm64.md @@ -29,8 +29,8 @@ here is the example pwd.yml file: ```yml services: backend: - image: frappe/erpnext:v15 - platform: linux/amd64 + image: frappe/erpnext:v16.19.1 + platform: linux/arm64 deploy: restart_policy: condition: on-failure @@ -39,8 +39,8 @@ services: - logs:/home/frappe/frappe-bench/logs configurator: - image: frappe/erpnext:v15 - platform: linux/amd64 + image: frappe/erpnext:v16.19.1 + platform: linux/arm64 deploy: restart_policy: condition: none @@ -68,8 +68,8 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v15 - platform: linux/amd64 + image: frappe/erpnext:v16.19.1 + platform: linux/arm64 deploy: restart_policy: condition: none @@ -101,7 +101,7 @@ services: db: image: mariadb:11.8 - platform: linux/amd64 + platform: linux/arm64 healthcheck: test: mysqladmin ping -h localhost --password=admin interval: 1s @@ -119,8 +119,8 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v15 - platform: linux/amd64 + image: frappe/erpnext:v16.19.1 + platform: linux/arm64 depends_on: - websocket deploy: @@ -144,8 +144,8 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v15 - platform: linux/amd64 + image: frappe/erpnext:v16.19.1 + platform: linux/arm64 deploy: restart_policy: condition: on-failure @@ -159,8 +159,8 @@ services: - logs:/home/frappe/frappe-bench/logs queue-short: - image: frappe/erpnext:v15 - platform: linux/amd64 + image: frappe/erpnext:v16.19.1 + platform: linux/arm64 deploy: restart_policy: condition: on-failure @@ -175,7 +175,7 @@ services: redis-queue: image: redis:6.2-alpine - platform: linux/amd64 + platform: linux/arm64 deploy: restart_policy: condition: on-failure @@ -184,14 +184,14 @@ services: redis-cache: image: redis:6.2-alpine - platform: linux/amd64 + platform: linux/arm64 deploy: restart_policy: condition: on-failure scheduler: - image: frappe/erpnext:v15 - platform: linux/amd64 + image: frappe/erpnext:v16.19.1 + platform: linux/arm64 deploy: restart_policy: condition: on-failure @@ -203,8 +203,8 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v15 - platform: linux/amd64 + image: frappe/erpnext:v16.19.1 + platform: linux/arm64 deploy: restart_policy: condition: on-failure From 6377a34c614a4999c897988784458dbf42c54b68 Mon Sep 17 00:00:00 2001 From: Chris Irag Date: Tue, 26 May 2026 19:42:21 +0800 Subject: [PATCH 276/279] docs(example): correct app installation command for crm subdomain in nginx proxy setup --- docs/02-setup/08-single-server-nginxproxy-example.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/02-setup/08-single-server-nginxproxy-example.md b/docs/02-setup/08-single-server-nginxproxy-example.md index 4f1c212f..ce4920f3 100644 --- a/docs/02-setup/08-single-server-nginxproxy-example.md +++ b/docs/02-setup/08-single-server-nginxproxy-example.md @@ -149,7 +149,7 @@ docker compose --project-name erpnext exec backend \ # crm.your-domain.com docker compose --project-name erpnext exec backend \ - bench new-site --mariadb-user-host-login-scope=% --db-root-password changeit --install-app erpnext --admin-password changeit crm.your-domain.com + bench new-site --mariadb-user-host-login-scope=% --db-root-password changeit --install-app crm --admin-password changeit crm.your-domain.com ``` ### Notes From 6695bb7b038638d90d0446c6bebdd137eb8de919 Mon Sep 17 00:00:00 2001 From: Daniel Radl Date: Tue, 26 May 2026 15:40:20 +0200 Subject: [PATCH 277/279] docs(ref): add assets doc --- .../02-docker-immutability.md | 4 +- .../08-reference/07-how-assets-are-handled.md | 62 +++++++++++++++++++ 2 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 docs/08-reference/07-how-assets-are-handled.md diff --git a/docs/01-getting-started/02-docker-immutability.md b/docs/01-getting-started/02-docker-immutability.md index c42ba65d..d3e65219 100644 --- a/docs/01-getting-started/02-docker-immutability.md +++ b/docs/01-getting-started/02-docker-immutability.md @@ -35,11 +35,11 @@ This allows you to: Installing apps into a running container is **not supported**. -`bench get-app` is an examples of an common but unsupported action. +`bench get-app` and `bench build` are examples of an common but unsupported actions. ### Why? -- Apps are part of the **Docker image** +- Apps and assets are part of the **Docker image** - Runtime changes are lost on container recreation - This ensures reproducibility and stability diff --git a/docs/08-reference/07-how-assets-are-handled.md b/docs/08-reference/07-how-assets-are-handled.md new file mode 100644 index 00000000..0bca581f --- /dev/null +++ b/docs/08-reference/07-how-assets-are-handled.md @@ -0,0 +1,62 @@ +--- +title: How Assets are handled +--- + +# Assets Reference + +## Problem + +The `sites` directory contains both persistent data (site config, uploaded files, etc.) and build-time artifacts (`sites/assets`). Mounting the entire `sites` directory as a Docker volume causes assets to be persisted alongside config, which leads to: + +- Stale assets surviving image updates +- Asset/manifest mismatches after rebuilds +- Assets being tied to the volume lifecycle rather than the image lifecycle + +## Solution + +Assets are moved out of the `sites` volume during the build process and replaced with a **symlink** later on. This means assets are always served from the image layer, while the rest of `sites` remains persistent. + +### How it works + +During the image build (`Containerfile`), the following is done: + +```dockerfile +RUN cp -r /home/frappe/frappe-bench/sites/assets /home/frappe/frappe-bench/assets && \ + rm -rf /home/frappe/frappe-bench/sites/assets +``` + +This runs **before** the `VOLUME` declaration, so the **`sites` volume does not contain any assets at all**. + +Additionally an `ENTRYPOINT` is added to the images which adds a **symlink** from `assets` to `site\assets`. + +> This is implemented in the entrypoint instead of baking the symlink directly into the image so it also works with pre-existing or already-initialized `sites` volumes. +> Since mounting a volume over `/home/frappe/frappe-bench/sites` hides the image contents at that path, any symlink created during the image build would not be visible inside the mounted volume. The entrypoint recreates the symlink at container startup, ensuring it always exists and automatically repairing older volumes that may not already contain it. + +At runtime: + +``` +/home/frappe/frappe-bench/ +β”œβ”€β”€ assets/ ← image layer (ephemeral, always matches the image) +β”œβ”€β”€ sites/ +β”‚ β”œβ”€β”€ assets -> /home/frappe/frappe-bench/assets ← symlink +β”‚ β”œβ”€β”€ common_site_config.json ← persisted in volume +β”‚ └── / ← persisted in volume +└── logs/ ← persisted in volume +``` + +### Volume behavior + +| Path | Persistent | Source | +| -------------------------- | ----------------------- | ---------------------- | +| `sites/` (except assets) | βœ… Yes | Named volume (`sites`) | +| `sites/assets` (symlink) | βœ… Yes (symlink itself) | Named volume (`sites`) | +| `assets/` (symlink target) | ❌ No | Image layer | +| `logs/` | βœ… Yes | Unnamed volume | + +The `sites/assets` symlink is stored inside the persistent `sites` volume, but its target (`/home/frappe/frappe-bench/assets`) comes from the container image. When the container is recreated or upgraded, the assets directory is recreated from the new image, ensuring assets always stay in sync with the running version. + +## Important: `bench build` at runtime + +Running `bench build` inside a running container will write new assets and eventually cause a mismatch between `assets.json` and the actual assets, breaking the UI. This can be recovered by recreating the containers + +> Note: restarting the containers is not sufficient β€” they need to be recreated to discard the writable layer. \ No newline at end of file From 6526ab8cd4d7c6969b9b44f95558590c89ab4347 Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 27 May 2026 01:51:34 +0000 Subject: [PATCH 278/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 3704b8f0..923b12d9 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/02-setup/04-env-variables.md -ERPNEXT_VERSION=v16.19.1 +ERPNEXT_VERSION=v16.20.0 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index 1fcde0cc..5d883c9e 100644 --- a/pwd.yml +++ b/pwd.yml @@ -1,6 +1,6 @@ services: backend: - image: frappe/erpnext:v16.19.1 + image: frappe/erpnext:v16.20.0 networks: - frappe_network deploy: @@ -16,7 +16,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v16.19.1 + image: frappe/erpnext:v16.20.0 networks: - frappe_network deploy: @@ -45,7 +45,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v16.19.1 + image: frappe/erpnext:v16.20.0 networks: - frappe_network deploy: @@ -101,7 +101,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v16.19.1 + image: frappe/erpnext:v16.20.0 networks: - frappe_network depends_on: @@ -127,7 +127,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v16.19.1 + image: frappe/erpnext:v16.20.0 networks: - frappe_network deploy: @@ -146,7 +146,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v16.19.1 + image: frappe/erpnext:v16.20.0 networks: - frappe_network deploy: @@ -183,7 +183,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v16.19.1 + image: frappe/erpnext:v16.20.0 networks: - frappe_network deploy: @@ -197,7 +197,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v16.19.1 + image: frappe/erpnext:v16.20.0 networks: - frappe_network deploy: From 6fccccf6d19892d31279245aa10fcf633968bb10 Mon Sep 17 00:00:00 2001 From: github-actions Date: Mon, 1 Jun 2026 06:39:33 +0000 Subject: [PATCH 279/279] chore: Update example.env --- example.env | 2 +- pwd.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example.env b/example.env index 923b12d9..ddfb9327 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,6 @@ # Reference: https://github.com/frappe/frappe_docker/blob/main/docs/02-setup/04-env-variables.md -ERPNEXT_VERSION=v16.20.0 +ERPNEXT_VERSION=v16.20.1 DB_PASSWORD=123 diff --git a/pwd.yml b/pwd.yml index 5d883c9e..779ab7c1 100644 --- a/pwd.yml +++ b/pwd.yml @@ -1,6 +1,6 @@ services: backend: - image: frappe/erpnext:v16.20.0 + image: frappe/erpnext:v16.20.1 networks: - frappe_network deploy: @@ -16,7 +16,7 @@ services: MARIADB_ROOT_PASSWORD: admin configurator: - image: frappe/erpnext:v16.20.0 + image: frappe/erpnext:v16.20.1 networks: - frappe_network deploy: @@ -45,7 +45,7 @@ services: - logs:/home/frappe/frappe-bench/logs create-site: - image: frappe/erpnext:v16.20.0 + image: frappe/erpnext:v16.20.1 networks: - frappe_network deploy: @@ -101,7 +101,7 @@ services: - db-data:/var/lib/mysql frontend: - image: frappe/erpnext:v16.20.0 + image: frappe/erpnext:v16.20.1 networks: - frappe_network depends_on: @@ -127,7 +127,7 @@ services: - "8080:8080" queue-long: - image: frappe/erpnext:v16.20.0 + image: frappe/erpnext:v16.20.1 networks: - frappe_network deploy: @@ -146,7 +146,7 @@ services: FRAPPE_REDIS_QUEUE: redis://redis-queue:6379 queue-short: - image: frappe/erpnext:v16.20.0 + image: frappe/erpnext:v16.20.1 networks: - frappe_network deploy: @@ -183,7 +183,7 @@ services: condition: on-failure scheduler: - image: frappe/erpnext:v16.20.0 + image: frappe/erpnext:v16.20.1 networks: - frappe_network deploy: @@ -197,7 +197,7 @@ services: - logs:/home/frappe/frappe-bench/logs websocket: - image: frappe/erpnext:v16.20.0 + image: frappe/erpnext:v16.20.1 networks: - frappe_network deploy: