Jeepay是一套适合互联网企业使用的开源支付系统,支持多渠道服务商和普通商户模式。已对接微信支付,支付宝,云闪付官方接口,支持聚合码支付。
docker pull library/${ROCKETMQ_IMAGE
docker run -d --name jeepay -p 1:1 --restart always ${ROCKETMQ_IMAGE:-swr.cn-south-1.myhuaweicloud.com/jeepay/rocketmq:5.3.1}
podman run -d --name jeepay -p 1:1 --restart always ${ROCKETMQ_IMAGE:-swr.cn-south-1.myhuaweicloud.com/jeepay/rocketmq:5.3.1}
skopeo inspect docker://docker.io/library/${ROCKETMQ_IMAGE:-swr.cn-south-1.myhuaweicloud.com/jeepay/rocketmq
oras pull ${ROCKETMQ_IMAGE:-swr.cn-south-1.myhuaweicloud.com/jeepay/rocketmq:5.3.1}
docker compose up -d
# 宝塔面板(BaoTa)"Docker 应用"专用 compose 文件
#
# 使用场景:
# - 宝塔 UI 上架 jeepay 应用,用户点击"安装"即部署
# - 与 docker-compose.yml(仓库自身的 Compose 部署)不同,宝塔场景下
# 用户不 git clone 源码,所有配置文件通过 jeepay-configs 这个 init
# 容器(alpine/git 镜像)从 git 拉下来再分发到宿主共享卷
#
# 镜像默认仓库:
# 所有业务镜像 + MySQL / Redis / RocketMQ / Nginx 默认走华为云 SWR 公开仓库
# (swr.cn-south-1.myhuaweicloud.com/jeepay/*),由计全官方维护,国内直拉,
# 不依赖 Docker Hub 加速器。alpine/git 仍用 Docker Hub(体积 < 20MB,一次
# 性拉取)。想回 Docker Hub 上游镜像时,可通过下面的 *_IMAGE 环境变量覆盖。
#
# 环境变量(由宝塔 app 模板声明):
# VERSION 业务镜像 tag(jeepay-manager/merchant/payment)
# CONFIG_REF 配置源 git ref(建议与 VERSION 同版本,或 master)
# UI_RELEASE 前端静态资源 release(默认 V3.0.0)
# MYSQL_ROOT_PASSWORD MySQL root 密码(默认 jeepaydb123456),同时贯穿到
# jeepay-configs 的 sed 替换,保证 yml 里 datasource 密码一致
# APP_PATH 宿主机部署根目录
# HOST_IP 对外绑定 IP
# WEB_HTTP_PORT1/2/3 对外端口(分别映射到 19216 / 19217 / 19218)
# CPUS / MEMORY_LIMIT nginx 资源限制
#
# 可选环境变量(想改镜像源时覆盖,各自带合理默认值):
# MYSQL_IMAGE / REDIS_IMAGE / ROCKETMQ_IMAGE / NGINX_IMAGE
# MANAGER_IMAGE / MERCHANT_IMAGE / PAYMENT_IMAGE
# JEEPAY_CONFIGS_IMAGE
#
# 首次安装后配置文件都在 ${APP_PATH}/jeepayhomes/jeepayConfigs/,用户可直接
# 编辑;jeepay-configs 用 cp -n 保护已存在文件不被覆盖;最新模板始终同步
# 到 ${APP_PATH}/jeepayhomes/jeepayConfigs/.latest/,升级时 diff 对比。
services:
# jeepay 配置中心:一次性 init 容器
# - 从 git 拉 ${CONFIG_REF} tag 的配置文件
# - cp -n 铺到共享卷,已存在文件跳过(保护用户编辑)
# - 最新模板同时刷到 .latest/,升级时 diff 对比
jeepay-configs:
image: ${JEEPAY_CONFIGS_IMAGE:-alpine/git:v2.45.2}
container_name: jeepay-configs
# alpine/git 的 ENTRYPOINT 默认是 git,清空后 command 才能直接 exec sh
entrypoint: []
environment:
# 贯穿到 sed 里替换 yml 的 datasource password(默认 jeepaydb123456)
MYSQL_ROOT_PASSWORD: "${MYSQL_ROOT_PASSWORD:-jeepaydb123456}"
volumes:
- ${APP_PATH}/jeepayhomes/:/jeepayhomes
command:
- sh
- -c
- |
set -e
rm -rf /tmp/jeepay-src
git clone --branch ${CONFIG_REF:-master} --depth 1 https://gitee.com/jeequan/jeepay.git /tmp/jeepay-src
mkdir -p /jeepayhomes/jeepayConfigs/db \
/jeepayhomes/jeepayConfigs/redis \
/jeepayhomes/jeepayConfigs/rocketmq \
/jeepayhomes/jeepayConfigs/service/manager \
/jeepayhomes/jeepayConfigs/service/merchant \
/jeepayhomes/jeepayConfigs/service/payment \
/jeepayhomes/jeepayConfigs/nginx/conf.d \
/jeepayhomes/jeepayConfigs/nginx/html
cp -n /tmp/jeepay-src/docs/install/include/my.cnf /jeepayhomes/jeepayConfigs/db/my.cnf || true
cp -n /tmp/jeepay-src/docs/sql/init.sql /jeepayhomes/jeepayConfigs/db/init.sql || true
cp -n /tmp/jeepay-src/docs/install/include/redis.conf /jeepayhomes/jeepayConfigs/redis/redis.conf || true
cp -n /tmp/jeepay-src/docker/rocketmq/broker/conf/broker.conf /jeepayhomes/jeepayConfigs/rocketmq/broker.conf || true
cp -n /tmp/jeepay-src/conf/manager/application.yml /jeepayhomes/jeepayConfigs/service/manager/application.yml || true
cp -n /tmp/jeepay-src/conf/merchant/application.yml /jeepayhomes/jeepayConfigs/service/merchant/application.yml || true
cp -n /tmp/jeepay-src/conf/payment/application.yml /jeepayhomes/jeepayConfigs/service/payment/application.yml || true
# 上游 conf/*/application.yml 里 datasource 密码是占位 "rootroot"(和仓库
# docker-compose.yml 的默认 MYSQL_ROOT_PASSWORD 一致),宝塔场景下 MySQL
# 初始化密码由 MYSQL_ROOT_PASSWORD 变量控制(默认 jeepaydb123456),不改
# 则 Access denied。用 grep 条件做幂等替换,只有还存在 "password: rootroot"
# 才改,尊重用户后续自定义。$$ 是给 compose 的转义,防止 compose YAML 解析
# 时把 shell 变量吞掉。
for svc in manager merchant payment; do
yml="/jeepayhomes/jeepayConfigs/service/$$svc/application.yml"
if [ -f "$$yml" ] && grep -q "password: rootroot" "$$yml"; then
sed -i "s|password: rootroot|password: $${MYSQL_ROOT_PASSWORD}|g" "$$yml"
echo "$$yml: datasource password rewrote"
fi
done
cp -n /tmp/jeepay-src/docs/install/include/nginx.conf /jeepayhomes/jeepayConfigs/nginx/nginx.conf || true
# nginx.conf 在 install.sh 场景下用 localhost:921x(nginx --net=host 可达),
# 但 compose 场景下 nginx 在 bridge 网络,localhost 解析不到后端。只要还能
# 找到 localhost:921x 就替换成 compose service 名;用户若已改过就不动。
if grep -q "proxy_pass http://localhost:921" /jeepayhomes/jeepayConfigs/nginx/nginx.conf 2>/dev/null; then
sed -i \
-e 's|proxy_pass http://localhost:9216|proxy_pass http://jeepaypayment:9216|g' \
-e 's|proxy_pass http://localhost:9217|proxy_pass http://jeepaymanager:9217|g' \
-e 's|proxy_pass http://localhost:9218|proxy_pass http://jeepaymerchant:9218|g' \
/jeepayhomes/jeepayConfigs/nginx/nginx.conf
echo "nginx.conf: localhost proxy_pass rewrote to compose service names"
fi
rm -rf /jeepayhomes/jeepayConfigs/.latest
mkdir -p /jeepayhomes/jeepayConfigs/.latest
cp -r /tmp/jeepay-src/conf /jeepayhomes/jeepayConfigs/.latest/conf
cp -r /tmp/jeepay-src/docs/install/include /jeepayhomes/jeepayConfigs/.latest/include
cp /tmp/jeepay-src/docker/rocketmq/broker/conf/broker.conf /jeepayhomes/jeepayConfigs/.latest/broker.conf || true
cp /tmp/jeepay-src/docs/sql/init.sql /jeepayhomes/jeepayConfigs/.latest/init.sql || true
# 前端静态资源(jeepay-ui 已打包发布到 gitee release)。目标目录已存在则跳过,
# 保护用户后续对 html/ 的改动(和 cp -n 同语义)
if [ ! -f /jeepayhomes/jeepayConfigs/nginx/html/jeepaymanager/index.html ]; then
echo "Downloading frontend html.tar.gz (release=${UI_RELEASE:-V3.0.0}) ..."
wget -q -O /tmp/html.tar.gz \
"https://gitee.com/jeequan/jeepay-ui/releases/download/${UI_RELEASE:-V3.0.0}/html.tar.gz"
tar xzf /tmp/html.tar.gz -C /jeepayhomes/jeepayConfigs/nginx/html/
rm -f /tmp/html.tar.gz
echo "Frontend extracted to nginx/html/"
else
echo "Frontend already present, skip download"
fi
echo "jeepay-configs ready (user edits preserved; upstream templates in .latest/)"
labels:
createdBy: "bt_apps"
networks:
- baota_net
# MySQL
mysql:
image: ${MYSQL_IMAGE:-swr.cn-south-1.myhuaweicloud.com/jeepay/mysql:8.0.25}
container_name: mysql8
hostname: mysql
restart: always
environment:
LANG: C.UTF-8
MYSQL_ROOT_PASSWORD: "${MYSQL_ROOT_PASSWORD:-jeepaydb123456}"
MYSQL_DATABASE: "jeepaydb"
depends_on:
jeepay-configs:
condition: service_completed_successfully
volumes:
- /etc/localtime:/etc/localtime:ro
- ${APP_PATH}/jeepayhomes/mysql/log:/var/log/mysql
- ${APP_PATH}/jeepayhomes/mysql/data:/var/lib/mysql
- ${APP_PATH}/jeepayhomes/mysql/mysql-files:/var/lib/mysql-files
- ${APP_PATH}/jeepayhomes/jeepayConfigs/db:/etc/mysql/conf.d
- ${APP_PATH}/jeepayhomes/jeepayConfigs/db/init.sql:/docker-entrypoint-initdb.d/init.sql:ro
healthcheck:
test: ["CMD-SHELL", "mysqladmin ping -h localhost -uroot -p$${MYSQL_ROOT_PASSWORD}"]
interval: 15s
timeout: 10s
retries: 10
start_period: 60s
labels:
createdBy: "bt_apps"
networks:
- baota_net
# Redis
redis:
image: ${REDIS_IMAGE:-swr.cn-south-1.myhuaweicloud.com/jeepay/redis:6.2.14}
container_name: redis6
hostname: redis
restart: always
depends_on:
jeepay-configs:
condition: service_completed_successfully
volumes:
- /etc/localtime:/etc/localtime:ro
- ${APP_PATH}/jeepayhomes/jeepayConfigs/redis/redis.conf:/etc/redis/redis.conf
- ${APP_PATH}/jeepayhomes/redis/data:/data
command: redis-server /etc/redis/redis.conf
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 10
start_period: 15s
labels:
createdBy: "bt_apps"
networks:
- baota_net
# RocketMQ NameServer
rocketmq-namesrv:
image: ${ROCKETMQ_IMAGE:-swr.cn-south-1.myhuaweicloud.com/jeepay/rocketmq:5.3.1}
platform: linux/amd64
container_name: rocketmq-namesrv
hostname: rocketmq-namesrv
restart: always
depends_on:
jeepay-configs:
condition: service_completed_successfully
volumes:
- /etc/localtime:/etc/localtime:ro
- ${APP_PATH}/jeepayhomes/rocketmq/namesrv/logs:/home/rocketmq/logs
environment:
JAVA_OPT_EXT: "-Xms256m -Xmx256m -Xmn128m"
command: sh mqnamesrv
healthcheck:
# rocketmq 镜像里 /bin/sh 是 dash,不支持 /dev/tcp,必须显式走 bash
test: ["CMD", "bash", "-c", "echo > /dev/tcp/localhost/9876"]
interval: 10s
timeout: 5s
retries: 10
start_period: 30s
labels:
createdBy: "bt_apps"
networks:
- baota_net
# RocketMQ Broker(brokerIP1 = 容器名,不依赖宿主网络布局)
rocketmq-broker:
image: ${ROCKETMQ_IMAGE:-swr.cn-south-1.myhuaweicloud.com/jeepay/rocketmq:5.3.1}
platform: linux/amd64
container_name: rocketmq-broker
hostname: rocketmq-broker
restart: always
user: "0:0"
depends_on:
rocketmq-namesrv:
condition: service_healthy
jeepay-configs:
condition: service_completed_successfully
volumes:
- /etc/localtime:/etc/localtime:ro
- ${APP_PATH}/jeepayhomes/rocketmq/broker/logs:/home/rocketmq/logs
- ${APP_PATH}/jeepayhomes/rocketmq/broker/store:/home/rocketmq/store
- ${APP_PATH}/jeepayhomes/jeepayConfigs/rocketmq/broker.conf:/home/rocketmq/rocketmq-5.3.1/conf/broker.conf:ro
environment:
NAMESRV_ADDR: "rocketmq-namesrv:9876"
JAVA_OPT_EXT: "-Xms512m -Xmx512m -Xmn256m"
command: sh mqbroker -n rocketmq-namesrv:9876 -c /home/rocketmq/rocketmq-5.3.1/conf/broker.conf
healthcheck:
test: ["CMD", "bash", "-c", "echo > /dev/tcp/localhost/10911"]
interval: 15s
timeout: 5s
retries: 15
start_period: 90s
labels:
createdBy: "bt_apps"
networks:
- baota_net
# jeepay 运营平台 API
jeepay-manager:
image: ${MANAGER_IMAGE:-swr.cn-south-1.myhuaweicloud.com/jeepay/jeepay-manager:${VERSION}}
container_name: jeepaymanager
restart: always
depends_on:
mysql:
condition: service_healthy
redis:
condition: service_healthy
rocketmq-broker:
condition: service_healthy
jeepay-configs:
condition: service_completed_successfully
volumes:
- /etc/localtime:/etc/localtime:ro
- ${APP_PATH}/jeepayhomes/service/logs:/jeepayhomes/service/logs
- ${APP_PATH}/jeepayhomes/service/uploads:/jeepayhomes/service/uploads
- ${APP_PATH}/jeepayhomes/jeepayConfigs/service/manager/application.yml:/jeepayhomes/service/app/application.yml
healthcheck:
test: ["CMD-SHELL", "curl -s -o /dev/null --max-time 3 http://127.0.0.1:9217 || exit 1"]
interval: 15s
timeout: 5s
retries: 12
start_period: 60s
labels:
createdBy: "bt_apps"
networks:
- baota_net
# jeepay 商户平台 API
jeepay-merchant:
image: ${MERCHANT_IMAGE:-swr.cn-south-1.myhuaweicloud.com/jeepay/jeepay-merchant:${VERSION}}
container_name: jeepaymerchant
restart: always
depends_on:
mysql:
condition: service_healthy
redis:
condition: service_healthy
rocketmq-broker:
condition: service_healthy
jeepay-configs:
condition: service_completed_successfully
volumes:
- /etc/localtime:/etc/localtime:ro
- ${APP_PATH}/jeepayhomes/service/logs:/jeepayhomes/service/logs
- ${APP_PATH}/jeepayhomes/service/uploads:/jeepayhomes/service/uploads
- ${APP_PATH}/jeepayhomes/jeepayConfigs/service/merchant/application.yml:/jeepayhomes/service/app/application.yml
healthcheck:
test: ["CMD-SHELL", "curl -s -o /dev/null --max-time 3 http://127.0.0.1:9218 || exit 1"]
interval: 15s
timeout: 5s
retries: 12
start_period: 60s
labels:
createdBy: "bt_apps"
networks:
- baota_net
# jeepay 支付网关 API
jeepay-payment:
image: ${PAYMENT_IMAGE:-swr.cn-south-1.myhuaweicloud.com/jeepay/jeepay-payment:${VERSION}}
container_name: jeepaypayment
restart: always
depends_on:
mysql:
condition: service_healthy
redis:
condition: service_healthy
rocketmq-broker:
condition: service_healthy
jeepay-configs:
condition: service_completed_successfully
volumes:
- /etc/localtime:/etc/localtime:ro
- ${APP_PATH}/jeepayhomes/service/logs:/jeepayhomes/service/logs
- ${APP_PATH}/jeepayhomes/service/uploads:/jeepayhomes/service/uploads
- ${APP_PATH}/jeepayhomes/jeepayConfigs/service/payment/application.yml:/jeepayhomes/service/app/application.yml
healthcheck:
test: ["CMD-SHELL", "curl -s -o /dev/null --max-time 3 http://127.0.0.1:9216 || exit 1"]
interval: 15s
timeout: 5s
retries: 12
start_period: 60s
labels:
createdBy: "bt_apps"
networks:
- baota_net
# nginx 网关(对外映射 19216 / 19217 / 19218)
BT_SERVICE_NAME6:
image: ${NGINX_IMAGE:-swr.cn-south-1.myhuaweicloud.com/jeepay/nginx:1.18.0}
container_name: nginx118
restart: always
deploy:
resources:
limits:
cpus: ${CPUS}
memory: ${MEMORY_LIMIT}
depends_on:
jeepay-payment:
condition: service_healthy
jeepay-manager:
condition: service_healthy
jeepay-merchant:
condition: service_healthy
jeepay-configs:
condition: service_completed_successfully
ports:
- ${HOST_IP}:${WEB_HTTP_PORT1}:19216
- ${HOST_IP}:${WEB_HTTP_PORT2}:19217
- ${HOST_IP}:${WEB_HTTP_PORT3}:19218
volumes:
- /etc/localtime:/etc/localtime:ro
- ${APP_PATH}/jeepayhomes/jeepayConfigs/nginx/nginx.conf:/etc/nginx/nginx.conf
- ${APP_PATH}/jeepayhomes/jeepayConfigs/nginx/conf.d:/etc/nginx/conf.d
- ${APP_PATH}/jeepayhomes/nginx/logs:/var/log/nginx
- ${APP_PATH}/jeepayhomes/jeepayConfigs/nginx/html:/usr/share/nginx/html
labels:
createdBy: "bt_apps"
networks:
- baota_net
networks:
baota_net:
external: true