@@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
docker build \
|
||||
--no-cache \
|
||||
--build-arg=FRAPPE_PATH=https://git.yierp.vip/erp/frappe.git \
|
||||
--build-arg=FRAPPE_BRANCH=main \
|
||||
--secret=id=apps_json,src=apps.json \
|
||||
--tag=yierp:15 \
|
||||
--file=images/yi15/Containerfile .
|
||||
@@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
docker build \
|
||||
--no-cache \
|
||||
--build-arg=FRAPPE_PATH=https://git.yierp.vip/erp/frappe.git \
|
||||
--build-arg=FRAPPE_BRANCH=main \
|
||||
--secret=id=apps_json,src=apps.json \
|
||||
--tag=yierp:16 \
|
||||
--file=images/yi16/Containerfile .
|
||||
@@ -1,7 +1,11 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
IMAGE_NAME="yierp"
|
||||
IMAGE_TAG="v260831"
|
||||
NO_CACHE="${NO_CACHE:-0}"
|
||||
BUILD_RETRIES="${BUILD_RETRIES:-3}"
|
||||
|
||||
echo "🚀 开始构建 YIERP 镜像..."
|
||||
echo "📦 镜像名称: ${IMAGE_NAME}:${IMAGE_TAG}"
|
||||
@@ -12,30 +16,58 @@ export DOCKER_BUILDKIT=1
|
||||
|
||||
# 构建镜像
|
||||
echo "🔨 开始构建镜像(这可能需要 5-15 分钟)..."
|
||||
docker build \
|
||||
--no-cache \
|
||||
--build-arg=FRAPPE_PATH=https://git.yierp.vip/erp/frappe.git \
|
||||
--build-arg=FRAPPE_BRANCH=main \
|
||||
--build-arg=FRAPPE_VERSION=version-16 \
|
||||
--secret=id=apps_json,src=apps.json \
|
||||
--tag=${IMAGE_NAME}:${IMAGE_TAG} \
|
||||
--file=images/yierp/Containerfile .
|
||||
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo ""
|
||||
echo "✅ 镜像构建成功: ${IMAGE_NAME}:${IMAGE_TAG}"
|
||||
echo ""
|
||||
echo "📊 镜像信息:"
|
||||
docker images ${IMAGE_NAME}:${IMAGE_TAG} --format "table {{.Repository}}:{{.Tag}}\t{{.Size}}\t{{.CreatedAt}}"
|
||||
|
||||
# 验证镜像中的应用
|
||||
echo ""
|
||||
echo "🔍 验证镜像中的应用列表:"
|
||||
if ! docker run --rm --user frappe --entrypoint bash ${IMAGE_NAME}:${IMAGE_TAG} -lc 'cd /home/frappe/frappe-bench && bench list-apps'; then
|
||||
echo "⚠️ 应用列表校验失败,但镜像已构建完成"
|
||||
fi
|
||||
BUILD_CACHE_FLAG=""
|
||||
if [ "$NO_CACHE" = "1" ]; then
|
||||
BUILD_CACHE_FLAG="--no-cache"
|
||||
echo "⚠️ 已启用无缓存构建"
|
||||
else
|
||||
echo "❌ 镜像构建失败,请检查错误信息"
|
||||
exit 1
|
||||
fi
|
||||
echo "✅ 使用缓存构建(更快、更稳定)"
|
||||
fi
|
||||
|
||||
attempt=1
|
||||
while [ "$attempt" -le "$BUILD_RETRIES" ]; do
|
||||
echo "🔁 构建尝试 ${attempt}/${BUILD_RETRIES}"
|
||||
if docker build \
|
||||
${BUILD_CACHE_FLAG} \
|
||||
--build-arg=FRAPPE_PATH=https://git.yierp.vip/erp/frappe.git \
|
||||
--build-arg=FRAPPE_BRANCH=main \
|
||||
--build-arg=FRAPPE_VERSION=version-16 \
|
||||
--secret=id=apps_json,src=apps.json \
|
||||
--tag=${IMAGE_NAME}:${IMAGE_TAG} \
|
||||
--file=images/yierp/Containerfile .; then
|
||||
break
|
||||
fi
|
||||
|
||||
if [ "$attempt" -eq "$BUILD_RETRIES" ]; then
|
||||
echo "❌ 镜像构建失败(已重试 ${BUILD_RETRIES} 次)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "⚠️ 构建失败,准备重试..."
|
||||
attempt=$((attempt + 1))
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "✅ 镜像构建成功: ${IMAGE_NAME}:${IMAGE_TAG}"
|
||||
echo ""
|
||||
echo "📊 镜像信息:"
|
||||
docker images ${IMAGE_NAME}:${IMAGE_TAG} --format "table {{.Repository}}:{{.Tag}}\t{{.Size}}\t{{.CreatedAt}}"
|
||||
|
||||
# 验证镜像中的应用
|
||||
echo ""
|
||||
echo "🔍 验证镜像中的应用列表:"
|
||||
if ! docker run --rm --user frappe --entrypoint bash ${IMAGE_NAME}:${IMAGE_TAG} -lc 'cd /home/frappe/frappe-bench && bench list-apps'; then
|
||||
echo "⚠️ 应用列表校验失败,但镜像已构建完成"
|
||||
fi
|
||||
|
||||
# 验证 Node / Yarn 与资产链路(资产内容由容器启动时自动修复)
|
||||
echo ""
|
||||
echo "🧪 验证前端工具链与资产链路:"
|
||||
docker run --rm --user frappe --entrypoint bash ${IMAGE_NAME}:${IMAGE_TAG} -lc '
|
||||
set -e
|
||||
cd /home/frappe/frappe-bench
|
||||
node --version
|
||||
yarn --version
|
||||
/usr/local/bin/check-assets.sh basic || true
|
||||
'
|
||||
+18
-10
@@ -30,10 +30,19 @@ services:
|
||||
condition: service_started
|
||||
command: >
|
||||
bash -ec "
|
||||
NODE24_BIN=$$(dirname $$(ls -1 /home/frappe/.nvm/versions/node/*/bin/node 2>/dev/null | sort | tail -n1 || true)) &&
|
||||
if [ -n "$$NODE24_BIN" ]; then
|
||||
ln -sf "$$NODE24_BIN/node" /usr/local/bin/node &&
|
||||
ln -sf "$$NODE24_BIN/npm" /usr/local/bin/npm &&
|
||||
[ -x "$$NODE24_BIN/npx" ] && ln -sf "$$NODE24_BIN/npx" /usr/local/bin/npx || true;
|
||||
[ -x "$$NODE24_BIN/yarn" ] && ln -sf "$$NODE24_BIN/yarn" /usr/local/bin/yarn || true;
|
||||
fi &&
|
||||
mkdir -p /home/frappe/frappe-bench/sites /home/frappe/frappe-bench/logs /home/frappe/frappe-bench/config/pids &&
|
||||
chown -R frappe:frappe /home/frappe/frappe-bench/sites /home/frappe/frappe-bench/logs /home/frappe/frappe-bench/config &&
|
||||
cd /home/frappe/frappe-bench &&
|
||||
su -s /bin/bash frappe -c 'cd /home/frappe/frappe-bench && find apps -mindepth 1 -maxdepth 1 -type d | while read -r app_dir; do [ -f "$$app_dir/modules.txt" ] && basename "$$app_dir"; done | sort > sites/apps.txt' &&
|
||||
su -s /bin/bash frappe -c 'sed -i "s#air-datepicker/dist/js/datepicker.min.js#air-datepicker/air-datepicker.js#g" /home/frappe/frappe-bench/apps/frappe/frappe/public/js/controls.bundle.js && sed -i "s#~air-datepicker/dist/css/datepicker.min#air-datepicker/air-datepicker.css#g" /home/frappe/frappe-bench/apps/frappe/frappe/public/scss/common/datepicker.scss && sed -i "s#~air-datepicker/air-datepicker.css#air-datepicker/air-datepicker.css#g" /home/frappe/frappe-bench/apps/frappe/frappe/public/scss/common/datepicker.scss && sed -i "s#air-datepicker/dist/js/i18n/#air-datepicker/locale/#g" /home/frappe/frappe-bench/apps/frappe/frappe/public/js/frappe/form/controls/datepicker_i18n.js && sed -i "s#air-datepicker/locale/datepicker.#air-datepicker/locale/#g" /home/frappe/frappe-bench/apps/frappe/frappe/public/js/frappe/form/controls/datepicker_i18n.js' &&
|
||||
su -s /bin/bash frappe -c 'cd /home/frappe/frappe-bench && find apps -mindepth 1 -maxdepth 1 -type d | while read -r app_dir; do app_name=$$(basename "$$app_dir"); [ -f "$$app_dir/$$app_name/modules.txt" ] && echo "$$app_name"; done | sort > sites/apps.txt' &&
|
||||
su -s /bin/bash frappe -c 'node -v && yarn -v' &&
|
||||
echo '=== 配置数据库连接 ===' &&
|
||||
su -s /bin/bash frappe -c 'cd /home/frappe/frappe-bench && bench set-mariadb-host "'"'"'$$DB_HOST'"'"'"' &&
|
||||
su -s /bin/bash frappe -c 'cd /home/frappe/frappe-bench && bench config set-common-config -c db_port "'"'"'$$DB_PORT'"'"'"' &&
|
||||
@@ -47,18 +56,17 @@ services:
|
||||
else
|
||||
echo '=== 站点已存在,跳过创建 ===';
|
||||
fi &&
|
||||
mkdir -p /home/frappe/frappe-bench/sites/assets &&
|
||||
if [ ! -f /home/frappe/frappe-bench/sites/assets/assets.json ]; then
|
||||
echo '{}' > /home/frappe/frappe-bench/sites/assets/assets.json;
|
||||
chown frappe:frappe /home/frappe/frappe-bench/sites/assets/assets.json;
|
||||
echo '=== 已写入兜底 assets.json ===';
|
||||
if ! /usr/local/bin/check-assets.sh full; then
|
||||
echo '=== 前端资产完整检查失败,开始自动修复 ===' &&
|
||||
su -s /bin/bash frappe -c 'cd /home/frappe/frappe-bench/apps/frappe && unset NODE_ENV npm_config_production && yarn install --check-files' &&
|
||||
su -s /bin/bash frappe -c 'cd /home/frappe/frappe-bench && bench build --force';
|
||||
else
|
||||
echo '=== 前端资产完整检查通过,跳过自动修复 ===';
|
||||
fi &&
|
||||
echo '=== 尝试安装前端依赖并构建资源(失败不阻塞启动) ===' &&
|
||||
su -s /bin/bash frappe -c 'cd /home/frappe/frappe-bench/apps/frappe && (yarn install --frozen-lockfile || yarn install)' || true &&
|
||||
su -s /bin/bash frappe -c 'cd /home/frappe/frappe-bench && bench build --app frappe' || true &&
|
||||
/usr/local/bin/check-assets.sh full &&
|
||||
su -s /bin/bash frappe -c 'cd /home/frappe/frappe-bench && bench use frontend' &&
|
||||
echo '=== 启动 ERPNext 服务 ===' &&
|
||||
exec su -s /bin/bash frappe -c 'cd /home/frappe/frappe-bench && bench serve --host 0.0.0.0 --port 8000'
|
||||
exec su -s /bin/bash frappe -c 'cd /home/frappe/frappe-bench && bench serve --host 0.0.0.0 --port 8000 --noreload'
|
||||
"
|
||||
|
||||
# ============================================
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
services:
|
||||
db:
|
||||
image: mariadb:11.8
|
||||
container_name: frappe-dev-db
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- frappe_dev_network
|
||||
ports:
|
||||
- "3306:3306"
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: admin
|
||||
MARIADB_ROOT_PASSWORD: admin
|
||||
command:
|
||||
- --character-set-server=utf8mb4
|
||||
- --collation-server=utf8mb4_unicode_ci
|
||||
- --skip-character-set-client-handshake
|
||||
healthcheck:
|
||||
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
|
||||
start_period: 10s
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
volumes:
|
||||
- frappe-dev-db-data:/var/lib/mysql
|
||||
|
||||
redis-cache:
|
||||
image: redis:6.2-alpine
|
||||
container_name: frappe-dev-redis-cache
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- frappe_dev_network
|
||||
ports:
|
||||
- "6379:6379"
|
||||
volumes:
|
||||
- frappe-dev-redis-cache-data:/data
|
||||
|
||||
redis-queue:
|
||||
image: redis:6.2-alpine
|
||||
container_name: frappe-dev-redis-queue
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- frappe_dev_network
|
||||
ports:
|
||||
- "6380:6379"
|
||||
volumes:
|
||||
- frappe-dev-redis-queue-data:/data
|
||||
|
||||
volumes:
|
||||
frappe-dev-db-data:
|
||||
frappe-dev-redis-cache-data:
|
||||
frappe-dev-redis-queue-data:
|
||||
|
||||
networks:
|
||||
frappe_dev_network:
|
||||
driver: bridge
|
||||
@@ -0,0 +1,58 @@
|
||||
ARG FRAPPE_BRANCH=version-16
|
||||
ARG FRAPPE_IMAGE_PREFIX=frappe
|
||||
|
||||
FROM frappe/build:v15 AS builder
|
||||
|
||||
ARG FRAPPE_BRANCH=version-16
|
||||
ARG FRAPPE_PATH=https://git.yierp.vip/erp/frappe.git
|
||||
ARG CACHE_BUST=""
|
||||
|
||||
USER frappe
|
||||
|
||||
RUN --mount=type=secret,id=apps_json,target=/opt/frappe/apps.json,uid=1000,gid=1000 \
|
||||
: "${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"; \
|
||||
fi && \
|
||||
bench init ${APP_INSTALL_ARGS}\
|
||||
--frappe-branch=${FRAPPE_BRANCH} \
|
||||
--frappe-path=${FRAPPE_PATH} \
|
||||
--no-procfile \
|
||||
--no-backups \
|
||||
--skip-redis-config-generation \
|
||||
--verbose \
|
||||
/home/frappe/frappe-bench && \
|
||||
cd /home/frappe/frappe-bench && \
|
||||
echo "{}" > sites/common_site_config.json && \
|
||||
find apps -mindepth 1 -path "*/.git" | xargs rm -fr
|
||||
|
||||
FROM frappe/base:v15 AS backend
|
||||
|
||||
USER frappe
|
||||
|
||||
COPY --from=builder --chown=frappe:frappe /home/frappe/frappe-bench /home/frappe/frappe-bench
|
||||
|
||||
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 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 ["start.sh"]
|
||||
@@ -0,0 +1,58 @@
|
||||
ARG FRAPPE_BRANCH=version-16
|
||||
ARG FRAPPE_IMAGE_PREFIX=frappe
|
||||
|
||||
FROM frappe/build:v16 AS builder
|
||||
|
||||
ARG FRAPPE_BRANCH=version-16
|
||||
ARG FRAPPE_PATH=https://git.yierp.vip/erp/frappe.git
|
||||
ARG CACHE_BUST=""
|
||||
|
||||
USER frappe
|
||||
|
||||
RUN --mount=type=secret,id=apps_json,target=/opt/frappe/apps.json,uid=1000,gid=1000 \
|
||||
: "${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"; \
|
||||
fi && \
|
||||
bench init ${APP_INSTALL_ARGS}\
|
||||
--frappe-branch=${FRAPPE_BRANCH} \
|
||||
--frappe-path=${FRAPPE_PATH} \
|
||||
--no-procfile \
|
||||
--no-backups \
|
||||
--skip-redis-config-generation \
|
||||
--verbose \
|
||||
/home/frappe/frappe-bench && \
|
||||
cd /home/frappe/frappe-bench && \
|
||||
echo "{}" > sites/common_site_config.json && \
|
||||
find apps -mindepth 1 -path "*/.git" | xargs rm -fr
|
||||
|
||||
FROM frappe/base:v16 AS backend
|
||||
|
||||
USER frappe
|
||||
|
||||
COPY --from=builder --chown=frappe:frappe /home/frappe/frappe-bench /home/frappe/frappe-bench
|
||||
|
||||
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 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 ["start.sh"]
|
||||
@@ -8,8 +8,8 @@ FROM ${FRAPPE_IMAGE_PREFIX}/build:${FRAPPE_VERSION} AS builder
|
||||
USER root
|
||||
RUN mkdir -p /home/frappe && chown frappe:frappe /home/frappe && \
|
||||
apt-get update && \
|
||||
apt-get install -y --no-install-recommends nodejs npm && \
|
||||
npm install -g yarn && \
|
||||
apt-get install -y --no-install-recommends nodejs npm yarnpkg && \
|
||||
ln -sf /usr/bin/yarnpkg /usr/local/bin/yarn && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ARG FRAPPE_BRANCH
|
||||
@@ -20,9 +20,25 @@ WORKDIR /home/frappe
|
||||
|
||||
WORKDIR /home/frappe/frappe-bench
|
||||
|
||||
# 降低 git/yarn 在弱网络下的握手失败概率
|
||||
RUN git config --global http.version HTTP/1.1 && \
|
||||
git config --global http.lowSpeedLimit 0 && \
|
||||
git config --global http.lowSpeedTime 999999 && \
|
||||
yarn config set network-timeout 600000 -g
|
||||
|
||||
# 克隆 Frappe 到 bench apps 目录(bench 运行期依赖该布局)
|
||||
RUN mkdir -p apps && git clone --depth 1 -b ${FRAPPE_BRANCH} ${FRAPPE_PATH} apps/frappe
|
||||
|
||||
# 将 air-datepicker 从 GitHub git 依赖替换为 npm 包,避免外网 TLS 抖动
|
||||
RUN node -e 'const fs=require("fs"); const p="/home/frappe/frappe-bench/apps/frappe/package.json"; const pkg=JSON.parse(fs.readFileSync(p,"utf8")); if(pkg.dependencies && pkg.dependencies["air-datepicker"]){ pkg.dependencies["air-datepicker"]="3.6.0"; } fs.writeFileSync(p, JSON.stringify(pkg, null, 2)+"\n");'
|
||||
|
||||
# 将 GitHub git 依赖替换为 codeload tarball,避免 git clone TLS 失败
|
||||
RUN set -e; \
|
||||
for f in /home/frappe/frappe-bench/apps/frappe/pyproject.toml /home/frappe/frappe-bench/apps/frappe/requirements*.txt; do \
|
||||
[ -f "$f" ] || continue; \
|
||||
sed -i -E 's#git\+https://github.com/([^/]+/[^@"]+)@([0-9A-Za-z._-]+)#https://codeload.github.com/\1/tar.gz/\2#g' "$f"; \
|
||||
done
|
||||
|
||||
# 创建 Python 虚拟环境
|
||||
RUN python3 -m venv env
|
||||
|
||||
@@ -34,14 +50,43 @@ RUN python3 -m pip install --no-cache-dir --upgrade pip wheel
|
||||
# 复制项目文件
|
||||
COPY --chown=frappe:frappe . .
|
||||
|
||||
# 新版 air-datepicker 不再提供 dist 路径,改写 Frappe 里的旧引用并校验
|
||||
RUN sed -i 's#air-datepicker/dist/js/datepicker.min.js#air-datepicker/air-datepicker.js#g' /home/frappe/frappe-bench/apps/frappe/frappe/public/js/controls.bundle.js && \
|
||||
sed -i 's#~air-datepicker/dist/css/datepicker.min#air-datepicker/air-datepicker.css#g' /home/frappe/frappe-bench/apps/frappe/frappe/public/scss/common/datepicker.scss && \
|
||||
sed -i 's#~air-datepicker/air-datepicker.css#air-datepicker/air-datepicker.css#g' /home/frappe/frappe-bench/apps/frappe/frappe/public/scss/common/datepicker.scss && \
|
||||
sed -i -E 's#air-datepicker/dist/js/i18n/datepicker\.([A-Za-z-]+)\.js#air-datepicker/locale/\1.js#g' /home/frappe/frappe-bench/apps/frappe/frappe/public/js/frappe/form/controls/datepicker_i18n.js && \
|
||||
sed -i -E 's#air-datepicker/locale/datepicker\.([A-Za-z-]+)\.js#air-datepicker/locale/\1.js#g' /home/frappe/frappe-bench/apps/frappe/frappe/public/js/frappe/form/controls/datepicker_i18n.js && \
|
||||
! grep -q 'air-datepicker/dist/' /home/frappe/frappe-bench/apps/frappe/frappe/public/js/controls.bundle.js && \
|
||||
! grep -q 'air-datepicker/dist/' /home/frappe/frappe-bench/apps/frappe/frappe/public/scss/common/datepicker.scss && \
|
||||
! grep -q 'air-datepicker/dist/' /home/frappe/frappe-bench/apps/frappe/frappe/public/js/frappe/form/controls/datepicker_i18n.js
|
||||
|
||||
# 验证 Node 安装
|
||||
RUN node --version && npm --version
|
||||
|
||||
# 强制安装 frappe 前端依赖,避免运行时缺少 fast-glob 等模块
|
||||
RUN cd /home/frappe/frappe-bench/apps/frappe && \
|
||||
unset NODE_ENV npm_config_production && \
|
||||
for i in 1 2 3; do \
|
||||
yarn install --check-files && break; \
|
||||
if [ "$i" -eq 3 ]; then \
|
||||
echo "❌ yarn install failed after 3 attempts"; \
|
||||
exit 1; \
|
||||
fi; \
|
||||
echo "⚠️ yarn install failed, retrying (attempt $((i + 1))/3)"; \
|
||||
done
|
||||
|
||||
# 安装 frappe
|
||||
RUN python3 -m pip install --no-cache-dir -e /home/frappe/frappe-bench/apps/frappe
|
||||
RUN for i in 1 2 3; do \
|
||||
python3 -m pip install --no-cache-dir -e /home/frappe/frappe-bench/apps/frappe && break; \
|
||||
if [ "$i" -eq 3 ]; then \
|
||||
echo "❌ pip install frappe failed after 3 attempts"; \
|
||||
exit 1; \
|
||||
fi; \
|
||||
echo "⚠️ pip install frappe failed, retrying (attempt $((i + 1))/3)"; \
|
||||
done
|
||||
|
||||
# 安装 apps.json 中定义的应用
|
||||
RUN --mount=type=secret,id=apps_json \
|
||||
RUN --mount=type=secret,id=apps_json,uid=1000,gid=1000,mode=0444 \
|
||||
if [ -f /run/secrets/apps_json ]; then \
|
||||
echo "📦 从 apps.json 安装应用..."; \
|
||||
export APPS_JSON_BASE64=$(cat /run/secrets/apps_json | base64 -w 0); \
|
||||
@@ -73,15 +118,50 @@ RUN --mount=type=secret,id=apps_json \
|
||||
# 清理 .git 目录以减小镜像大小
|
||||
RUN find apps -mindepth 1 -path "*/.git" | xargs rm -fr
|
||||
|
||||
# 为所有包含 package.json 的应用安装前端依赖
|
||||
RUN set -e; \
|
||||
cd /home/frappe/frappe-bench; \
|
||||
find apps -mindepth 1 -maxdepth 1 -type d | while read -r app_dir; do \
|
||||
if [ -f "$app_dir/package.json" ]; then \
|
||||
echo "Installing JS deps for $(basename "$app_dir")"; \
|
||||
(cd "$app_dir" && unset NODE_ENV npm_config_production && \
|
||||
for i in 1 2 3; do \
|
||||
yarn install --check-files && break; \
|
||||
if [ "$i" -eq 3 ]; then \
|
||||
echo "❌ yarn install failed for $(basename "$app_dir") after 3 attempts"; \
|
||||
exit 1; \
|
||||
fi; \
|
||||
echo "⚠️ yarn install failed for $(basename "$app_dir"), retrying (attempt $((i + 1))/3)"; \
|
||||
done); \
|
||||
fi; \
|
||||
done
|
||||
|
||||
FROM ${FRAPPE_IMAGE_PREFIX}/base:${FRAPPE_VERSION} AS backend
|
||||
|
||||
USER root
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends nodejs npm yarnpkg && \
|
||||
ln -sf /usr/bin/yarnpkg /usr/local/bin/yarn && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# 优先使用 base 镜像中 nvm 的 Node 24,满足前端构建对 node>=24 的要求
|
||||
RUN set -e; \
|
||||
NODE_BIN_DIR="$(dirname "$(ls -1 /home/frappe/.nvm/versions/node/*/bin/node | sort | tail -n1)")"; \
|
||||
ln -sf "$NODE_BIN_DIR/node" /usr/local/bin/node; \
|
||||
ln -sf "$NODE_BIN_DIR/npm" /usr/local/bin/npm; \
|
||||
ln -sf "$NODE_BIN_DIR/npx" /usr/local/bin/npx; \
|
||||
if [ -x "$NODE_BIN_DIR/yarn" ]; then ln -sf "$NODE_BIN_DIR/yarn" /usr/local/bin/yarn; fi
|
||||
|
||||
# 复制完整 bench(含 env),确保运行时具备 frappe 依赖
|
||||
COPY --from=builder /home/frappe/frappe-bench /home/frappe/frappe-bench
|
||||
|
||||
COPY resources/core/main-entrypoint.sh /usr/local/bin/main-entrypoint.sh
|
||||
RUN chmod 755 /usr/local/bin/main-entrypoint.sh
|
||||
|
||||
COPY resources/core/check-assets.sh /usr/local/bin/check-assets.sh
|
||||
RUN chmod 755 /usr/local/bin/check-assets.sh
|
||||
|
||||
WORKDIR /home/frappe/frappe-bench
|
||||
|
||||
ENV PATH="/home/frappe/frappe-bench/env/bin:${PATH}"
|
||||
|
||||
Executable
+86
@@ -0,0 +1,86 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
BENCH_PATH="/home/frappe/frappe-bench"
|
||||
SITES_ASSETS_LINK="${BENCH_PATH}/sites/assets"
|
||||
ASSETS_DIR="${BENCH_PATH}/assets"
|
||||
ASSETS_JSON="${ASSETS_DIR}/assets.json"
|
||||
MODE="${1:-full}"
|
||||
|
||||
echo "=== 前端资产自检开始 ==="
|
||||
|
||||
if [ ! -L "$SITES_ASSETS_LINK" ]; then
|
||||
echo "❌ 失败: ${SITES_ASSETS_LINK} 不是软链接"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
LINK_TARGET="$(readlink "$SITES_ASSETS_LINK")"
|
||||
if [ "$LINK_TARGET" != "$ASSETS_DIR" ]; then
|
||||
echo "❌ 失败: sites/assets 软链接目标错误: ${LINK_TARGET}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$ASSETS_JSON" ]; then
|
||||
echo "❌ 失败: 未找到 ${ASSETS_JSON}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$MODE" = "basic" ]; then
|
||||
echo "✅ 基础检查通过: 软链接与 assets.json 存在"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
python3 - <<'PY'
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
|
||||
bench = "/home/frappe/frappe-bench"
|
||||
assets_dir = os.path.join(bench, "assets")
|
||||
assets_json = os.path.join(assets_dir, "assets.json")
|
||||
|
||||
with open(assets_json, "r", encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
|
||||
css_paths = []
|
||||
|
||||
def walk(value):
|
||||
if isinstance(value, dict):
|
||||
for v in value.values():
|
||||
walk(v)
|
||||
elif isinstance(value, list):
|
||||
for item in value:
|
||||
walk(item)
|
||||
elif isinstance(value, str) and value.endswith(".css"):
|
||||
css_paths.append(value)
|
||||
|
||||
walk(data)
|
||||
|
||||
if not css_paths:
|
||||
print("❌ 失败: assets.json 中未发现 CSS 资源路径")
|
||||
sys.exit(1)
|
||||
|
||||
missing = []
|
||||
for p in css_paths:
|
||||
rel = p
|
||||
if rel.startswith("/assets/"):
|
||||
rel = rel[len("/assets/"):]
|
||||
elif rel.startswith("assets/"):
|
||||
rel = rel[len("assets/"):]
|
||||
rel = rel.lstrip("/")
|
||||
full = os.path.join(assets_dir, rel)
|
||||
if not os.path.isfile(full):
|
||||
missing.append((p, full))
|
||||
|
||||
if missing:
|
||||
print("❌ 失败: 下列 CSS 资源在磁盘上不存在:")
|
||||
for src, full in missing[:10]:
|
||||
print(f" - {src} -> {full}")
|
||||
if len(missing) > 10:
|
||||
print(f" ... 还有 {len(missing) - 10} 个")
|
||||
sys.exit(1)
|
||||
|
||||
print(f"✅ 通过: 共检测到 {len(css_paths)} 个 CSS 路径,文件均存在")
|
||||
PY
|
||||
|
||||
echo "=== 前端资产自检通过 ==="
|
||||
@@ -17,8 +17,9 @@ mkdir -p "$SITES_PATH" "$LOGS_PATH" "$BAKED_PATH" "$CONFIG_PATH" "$PIDS_PATH" "$
|
||||
|
||||
# Rebuild apps.txt from app directories that look like Frappe apps.
|
||||
find "$APPS_PATH" -mindepth 1 -maxdepth 1 -type d | while read -r app_dir; do
|
||||
if [ -f "$app_dir/modules.txt" ]; then
|
||||
basename "$app_dir"
|
||||
app_name="$(basename "$app_dir")"
|
||||
if [ -f "$app_dir/$app_name/modules.txt" ]; then
|
||||
echo "$app_name"
|
||||
fi
|
||||
done | sort > "$APPS_TXT_PATH"
|
||||
|
||||
|
||||
@@ -0,0 +1,244 @@
|
||||
services:
|
||||
backend:
|
||||
image: yierp:15
|
||||
networks:
|
||||
- frappe_network
|
||||
deploy:
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
volumes:
|
||||
- sites:/home/frappe/frappe-bench/sites
|
||||
- logs:/home/frappe/frappe-bench/logs
|
||||
environment:
|
||||
DB_HOST: db
|
||||
DB_PORT: "3306"
|
||||
MYSQL_ROOT_PASSWORD: admin
|
||||
MARIADB_ROOT_PASSWORD: admin
|
||||
depends_on:
|
||||
configurator:
|
||||
condition: service_completed_successfully
|
||||
|
||||
configurator:
|
||||
image: yierp:15
|
||||
networks:
|
||||
- frappe_network
|
||||
deploy:
|
||||
restart_policy:
|
||||
condition: none
|
||||
entrypoint:
|
||||
- bash
|
||||
- -c
|
||||
command:
|
||||
- >
|
||||
ls -1 apps > sites/apps.txt;
|
||||
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;
|
||||
environment:
|
||||
DB_HOST: db
|
||||
DB_PORT: "3306"
|
||||
REDIS_CACHE: redis-cache:6379
|
||||
REDIS_QUEUE: redis-queue:6379
|
||||
SOCKETIO_PORT: "9000"
|
||||
volumes:
|
||||
- sites:/home/frappe/frappe-bench/sites
|
||||
- logs:/home/frappe/frappe-bench/logs
|
||||
|
||||
create-site:
|
||||
image: yierp:15
|
||||
networks:
|
||||
- frappe_network
|
||||
deploy:
|
||||
restart_policy:
|
||||
condition: none
|
||||
volumes:
|
||||
- sites:/home/frappe/frappe-bench/sites
|
||||
- logs:/home/frappe/frappe-bench/logs
|
||||
entrypoint:
|
||||
- bash
|
||||
- -c
|
||||
command:
|
||||
- >
|
||||
wait-for-it -t 120 db:3306;
|
||||
wait-for-it -t 120 redis-cache:6379;
|
||||
wait-for-it -t 120 redis-queue:6379;
|
||||
export start=`date +%s`;
|
||||
until [[ -n `grep -hs ^ sites/common_site_config.json | jq -r ".db_host // empty"` ]] && \
|
||||
[[ -n `grep -hs ^ sites/common_site_config.json | jq -r ".redis_cache // empty"` ]] && \
|
||||
[[ -n `grep -hs ^ sites/common_site_config.json | jq -r ".redis_queue // empty"` ]];
|
||||
do
|
||||
echo "Waiting for sites/common_site_config.json to be created";
|
||||
sleep 5;
|
||||
if (( `date +%s`-start > 120 )); then
|
||||
echo "could not find sites/common_site_config.json with required keys";
|
||||
exit 1
|
||||
fi
|
||||
done;
|
||||
echo "sites/common_site_config.json found";
|
||||
if [ -d "sites/frontend" ]; then
|
||||
echo "Site frontend already exists, skipping creation";
|
||||
else
|
||||
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;
|
||||
fi;
|
||||
|
||||
db:
|
||||
image: mariadb:11.8
|
||||
networks:
|
||||
- frappe_network
|
||||
healthcheck:
|
||||
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
|
||||
start_period: 5s
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
deploy:
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
command:
|
||||
- --character-set-server=utf8mb4
|
||||
- --collation-server=utf8mb4_unicode_ci
|
||||
- --skip-character-set-client-handshake
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: admin
|
||||
MARIADB_ROOT_PASSWORD: admin
|
||||
volumes:
|
||||
- db-data:/var/lib/mysql
|
||||
|
||||
frontend:
|
||||
image: yierp:15
|
||||
networks:
|
||||
- frappe_network
|
||||
depends_on:
|
||||
- websocket
|
||||
- backend
|
||||
deploy:
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
command:
|
||||
- nginx-entrypoint.sh
|
||||
environment:
|
||||
BACKEND: backend:8000
|
||||
FRAPPE_SITE_NAME_HEADER: frontend
|
||||
SOCKETIO: websocket:9000
|
||||
UPSTREAM_REAL_IP_ADDRESS: 127.0.0.1
|
||||
UPSTREAM_REAL_IP_HEADER: X-Forwarded-For
|
||||
UPSTREAM_REAL_IP_RECURSIVE: "off"
|
||||
PROXY_READ_TIMEOUT: 120
|
||||
CLIENT_MAX_BODY_SIZE: 50m
|
||||
volumes:
|
||||
- sites:/home/frappe/frappe-bench/sites
|
||||
- logs:/home/frappe/frappe-bench/logs
|
||||
ports:
|
||||
- "8080:8080"
|
||||
|
||||
queue-long:
|
||||
image: yierp:15
|
||||
networks:
|
||||
- frappe_network
|
||||
deploy:
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
command:
|
||||
- bench
|
||||
- worker
|
||||
- --queue
|
||||
- long,default,short
|
||||
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
|
||||
depends_on:
|
||||
configurator:
|
||||
condition: service_completed_successfully
|
||||
|
||||
queue-short:
|
||||
image: yierp:15
|
||||
networks:
|
||||
- frappe_network
|
||||
deploy:
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
command:
|
||||
- bench
|
||||
- worker
|
||||
- --queue
|
||||
- short,default
|
||||
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
|
||||
depends_on:
|
||||
configurator:
|
||||
condition: service_completed_successfully
|
||||
|
||||
redis-queue:
|
||||
image: redis:6.2-alpine
|
||||
networks:
|
||||
- frappe_network
|
||||
deploy:
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
volumes:
|
||||
- redis-queue-data:/data
|
||||
|
||||
redis-cache:
|
||||
image: redis:6.2-alpine
|
||||
networks:
|
||||
- frappe_network
|
||||
deploy:
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
|
||||
scheduler:
|
||||
image: yierp:15
|
||||
networks:
|
||||
- frappe_network
|
||||
deploy:
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
command:
|
||||
- bench
|
||||
- schedule
|
||||
volumes:
|
||||
- sites:/home/frappe/frappe-bench/sites
|
||||
- logs:/home/frappe/frappe-bench/logs
|
||||
depends_on:
|
||||
configurator:
|
||||
condition: service_completed_successfully
|
||||
|
||||
websocket:
|
||||
image: yierp:15
|
||||
networks:
|
||||
- frappe_network
|
||||
deploy:
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
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
|
||||
depends_on:
|
||||
configurator:
|
||||
condition: service_completed_successfully
|
||||
|
||||
volumes:
|
||||
db-data:
|
||||
redis-queue-data:
|
||||
sites:
|
||||
logs:
|
||||
|
||||
networks:
|
||||
frappe_network:
|
||||
driver: bridge
|
||||
@@ -0,0 +1,247 @@
|
||||
services:
|
||||
backend:
|
||||
image: yierp:16
|
||||
networks:
|
||||
- frappe_network
|
||||
deploy:
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
volumes:
|
||||
- sites:/home/frappe/frappe-bench/sites
|
||||
- logs:/home/frappe/frappe-bench/logs
|
||||
environment:
|
||||
DB_HOST: db
|
||||
DB_PORT: "3306"
|
||||
MYSQL_ROOT_PASSWORD: admin
|
||||
MARIADB_ROOT_PASSWORD: admin
|
||||
depends_on:
|
||||
configurator:
|
||||
condition: service_completed_successfully
|
||||
|
||||
configurator:
|
||||
image: yierp:16
|
||||
networks:
|
||||
- frappe_network
|
||||
|
||||
deploy:
|
||||
restart_policy:
|
||||
condition: none
|
||||
entrypoint:
|
||||
- bash
|
||||
- -c
|
||||
command:
|
||||
- >
|
||||
ls -1 apps > sites/apps.txt;
|
||||
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;
|
||||
environment:
|
||||
DB_HOST: db
|
||||
DB_PORT: "3306"
|
||||
REDIS_CACHE: redis-cache:6379
|
||||
REDIS_QUEUE: redis-queue:6379
|
||||
SOCKETIO_PORT: "9000"
|
||||
volumes:
|
||||
- sites:/home/frappe/frappe-bench/sites
|
||||
- logs:/home/frappe/frappe-bench/logs
|
||||
|
||||
create-site:
|
||||
image: yierp:16
|
||||
networks:
|
||||
- frappe_network
|
||||
deploy:
|
||||
restart_policy:
|
||||
condition: none
|
||||
volumes:
|
||||
- sites:/home/frappe/frappe-bench/sites
|
||||
- logs:/home/frappe/frappe-bench/logs
|
||||
entrypoint:
|
||||
- bash
|
||||
- -c
|
||||
command:
|
||||
- >
|
||||
wait-for-it -t 120 db:3306;
|
||||
wait-for-it -t 120 redis-cache:6379;
|
||||
wait-for-it -t 120 redis-queue:6379;
|
||||
export start=`date +%s`;
|
||||
until [[ -n `grep -hs ^ sites/common_site_config.json | jq -r ".db_host // empty"` ]] && \
|
||||
[[ -n `grep -hs ^ sites/common_site_config.json | jq -r ".redis_cache // empty"` ]] && \
|
||||
[[ -n `grep -hs ^ sites/common_site_config.json | jq -r ".redis_queue // empty"` ]];
|
||||
do
|
||||
echo "Waiting for sites/common_site_config.json to be created";
|
||||
sleep 5;
|
||||
if (( `date +%s`-start > 120 )); then
|
||||
echo "could not find sites/common_site_config.json with required keys";
|
||||
exit 1
|
||||
fi
|
||||
done;
|
||||
echo "sites/common_site_config.json found";
|
||||
if [ -d "sites/frontend" ]; then
|
||||
echo "Site frontend already exists, skipping creation";
|
||||
else
|
||||
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;
|
||||
fi;
|
||||
|
||||
db:
|
||||
image: mariadb:11.8
|
||||
networks:
|
||||
- frappe_network
|
||||
ports:
|
||||
- "3306:3306"
|
||||
healthcheck:
|
||||
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
|
||||
start_period: 5s
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
deploy:
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
command:
|
||||
- --character-set-server=utf8mb4
|
||||
- --collation-server=utf8mb4_unicode_ci
|
||||
- --skip-character-set-client-handshake
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: admin
|
||||
MARIADB_ROOT_PASSWORD: admin
|
||||
volumes:
|
||||
- db-data:/var/lib/mysql
|
||||
|
||||
frontend:
|
||||
image: yierp:16
|
||||
networks:
|
||||
- frappe_network
|
||||
depends_on:
|
||||
- websocket
|
||||
- backend
|
||||
deploy:
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
command:
|
||||
- nginx-entrypoint.sh
|
||||
environment:
|
||||
BACKEND: backend:8000
|
||||
FRAPPE_SITE_NAME_HEADER: frontend
|
||||
SOCKETIO: websocket:9000
|
||||
UPSTREAM_REAL_IP_ADDRESS: 127.0.0.1
|
||||
UPSTREAM_REAL_IP_HEADER: X-Forwarded-For
|
||||
UPSTREAM_REAL_IP_RECURSIVE: "off"
|
||||
PROXY_READ_TIMEOUT: 120
|
||||
CLIENT_MAX_BODY_SIZE: 50m
|
||||
volumes:
|
||||
- sites:/home/frappe/frappe-bench/sites
|
||||
- logs:/home/frappe/frappe-bench/logs
|
||||
ports:
|
||||
- "8080:8080"
|
||||
|
||||
queue-long:
|
||||
image: yierp:16
|
||||
networks:
|
||||
- frappe_network
|
||||
deploy:
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
command:
|
||||
- bench
|
||||
- worker
|
||||
- --queue
|
||||
- long,default,short
|
||||
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
|
||||
depends_on:
|
||||
configurator:
|
||||
condition: service_completed_successfully
|
||||
|
||||
queue-short:
|
||||
image: yierp:16
|
||||
networks:
|
||||
- frappe_network
|
||||
deploy:
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
command:
|
||||
- bench
|
||||
- worker
|
||||
- --queue
|
||||
- short,default
|
||||
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
|
||||
depends_on:
|
||||
configurator:
|
||||
condition: service_completed_successfully
|
||||
|
||||
redis-queue:
|
||||
image: redis:6.2-alpine
|
||||
networks:
|
||||
- frappe_network
|
||||
deploy:
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
volumes:
|
||||
- redis-queue-data:/data
|
||||
|
||||
redis-cache:
|
||||
image: redis:6.2-alpine
|
||||
networks:
|
||||
- frappe_network
|
||||
deploy:
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
|
||||
scheduler:
|
||||
image: yierp:16
|
||||
networks:
|
||||
- frappe_network
|
||||
deploy:
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
command:
|
||||
- bench
|
||||
- schedule
|
||||
volumes:
|
||||
- sites:/home/frappe/frappe-bench/sites
|
||||
- logs:/home/frappe/frappe-bench/logs
|
||||
depends_on:
|
||||
configurator:
|
||||
condition: service_completed_successfully
|
||||
|
||||
websocket:
|
||||
image: yierp:16
|
||||
networks:
|
||||
- frappe_network
|
||||
deploy:
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
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
|
||||
depends_on:
|
||||
configurator:
|
||||
condition: service_completed_successfully
|
||||
|
||||
volumes:
|
||||
db-data:
|
||||
redis-queue-data:
|
||||
sites:
|
||||
logs:
|
||||
|
||||
networks:
|
||||
frappe_network:
|
||||
driver: bridge
|
||||
Reference in New Issue
Block a user