文档:统一本地环境共享数据库流程

This commit is contained in:
WuYongJie 2026-07-23 21:47:50 +08:00
parent 287a3eb565
commit fa583c7e74
8 changed files with 282 additions and 200 deletions

View File

@ -1,119 +1,129 @@
# CaiWuXiTong 本地部署说明
# CaiWuXiTong 本地测试环境
## 项目概况
- 基于 [Akaunting](https://akaunting.com) 二次开发的"江陵"版财务系统
- 技术栈:PHP 8.3 + Laravel + Vue + Apache + MySQL 8.0
- 访问端口:**18088**
本说明用于开发者在自己的电脑上启动项目。项目使用 Docker,默认访问地址为:
## 文件清单(本地部署新增)
| 文件 | 作用 |
|------|------|
| `docker-compose.local.yml` | 本地 compose:app + mysql,bridge 网络 |
| `deploy/Dockerfile.local` | 本地 Dockerfile:基于原 Dockerfile,增加 composer/npm 依赖安装 |
| `deploy/local-init.sh` | 一键构建+启动+初始化脚本 |
| `runtime/.env` | 应用环境配置(挂载到容器 `/var/www/html/.env`) |
| `LOCAL_DEPLOY.md` | 本说明 |
```text
http://127.0.0.1:18088
```
> 原 `compose.jiangling.yml` / `deploy/Dockerfile` 未改动,保留团队主线一致性。
## 先理解数据库关系
本地 Compose 中的 MySQL 只负责第一次启动,让开发者能够使用临时账号进入系统。
登录后必须在:
```text
系统设置 → 数据库管理 → 系统数据库 → 修改连接
```
填写负责人提供的“财务系统配置数据库”参数并点击“测试并保存”。保存成功后:
- 用户、侧边栏、系统设置和云数据库登记统一来自系统数据库;
- 两个云数据库自动加载;
- 云数据库共享密码由系统数据库登录密码解锁;
- 每台开发机可以使用自己的 `APP_KEY`,禁止复制生产环境或其他开发者的 `APP_KEY`;
- 不需要在本机填写 `DB_JIANSUN_*` 或 `DB_OPERATIONS_REPLICA_*`。
系统数据库只保存配置,不代理 SQL Server 网络。开发机仍需能够直接访问对应云数据库;如果共享配置可以解锁,但 `SELECT 1` 失败,再检查当前网络、白名单、VPN或受限隧道。
## 第一次启动
前提:Docker Desktop 已启动。
在 Git Bash、WSL、macOS 或 Linux 终端中执行:
## 一键部署
```bash
cd CaiWuXiTong_src
bash deploy/local-init.sh
```
## 手动步骤
```bash
# 1. 启动
docker compose -f docker-compose.local.yml up -d --build
脚本会:
# 2. 初始化数据库与管理员
docker compose -f docker-compose.local.yml exec app \
php artisan install --no-interaction \
--db-host=mysql --db-name=akaunting \
--db-username=akaunting --db-password=akaunting123 \
--admin-email=admin@company.com --admin-password=admin123 \
--locale=zh-CN
1. 在 `runtime/.env` 不存在时生成仅供本机使用的环境配置和随机 `APP_KEY`;
2. 构建并启动应用和临时 MySQL;
3. 初始化临时管理员;
4. 检查登录页是否可以访问;
5. 提示下一步配置系统数据库。
# 3. 访问
open http://127.0.0.1:18088
首次临时登录:
```text
邮箱:local-bootstrap@caiwu.test
密码:LocalOnly-18088!
```
## 登录信息
- **地址**:http://127.0.0.1:18088
- **邮箱**:`admin@company.com`
- **密码**:`admin123`
这个账号只存在于本机临时数据库中。系统数据库切换完成后,请使用系统数据库里属于自己的账号登录,不要继续把临时账号当作团队共享账号。
## 配置系统数据库
1. 打开 `http://127.0.0.1:18088/auth/login`。
2. 首次使用临时账号登录。
3. 打开“系统设置 → 数据库管理”。
4. 在固定的“系统数据库”区域点击“修改连接”。
5. 填写负责人提供的主机、端口、数据库名、账号、密码和 TLS 设置。
6. 点击“测试并保存”。
7. 返回数据库管理页面,确认两个云数据库已经自动出现。
8. 退出临时账号,使用系统数据库中属于自己的账号重新登录。
保存系统数据库时,程序会自动设置:
```dotenv
UPSTREAM_STORED_CONFIG_ENABLED=true
UPSTREAM_LOCAL_CONFIG_ENABLED=false
```
不要手工把 `DB_HOST` 改回 `mysql`,否则会重新使用互不相干的本机用户和配置。
## 验收共享云数据库
仅看到两条云数据库记录并不代表业务读取已经成功。验收时应在应用容器内完成:
1. 确认两条记录都显示启用;
2. 确认共享密码可以解锁;
3. 分别执行受控的只读 `SELECT 1`;
4. 至少验证一个已登记的真实业务查询;
5. 检查页面或 API 的数据状态和同步时间。
禁止为了排错复制别人的 `.env`、生产 `APP_KEY` 或云数据库密码。
## 常用命令
## 常用维护命令
```bash
# 查看日志
# 查看状态
docker compose -f docker-compose.local.yml ps
# 查看应用日志
docker compose -f docker-compose.local.yml logs -f app
# 重启
# 重启应用
docker compose -f docker-compose.local.yml restart app
# 进入容器
docker compose -f docker-compose.local.yml exec app bash
# 进入 MySQL
docker compose -f docker-compose.local.yml exec mysql mysql -uakaunting -pakaunting123 akaunting
# 清缓存
# 清理应用缓存
docker compose -f docker-compose.local.yml exec app php artisan optimize:clear
# 重新迁移
docker compose -f docker-compose.local.yml exec app php artisan migrate --force
# 停止 / 启动 / 销毁
# 停止容器,但保留本地数据
docker compose -f docker-compose.local.yml stop
# 再次启动
docker compose -f docker-compose.local.yml start
docker compose -f docker-compose.local.yml down # 仅停容器
docker compose -f docker-compose.local.yml down -v # 同时删除数据卷(会清空数据库!)
```
## 端口映射
| 服务 | 宿主机端口 | 容器端口 |
|------|-----------|----------|
| Akaunting (Apache) | 18088 | 18088 |
| MySQL | 13306 | 3306 |
不要执行 `docker compose down -v`、删除数据库卷或强制迁移。确需重置本地临时库时,先确认不会影响当前系统数据库配置并找负责人或 Codex处理。
## 数据卷
- `jiangling_storage` —— 应用上传文件、日志、缓存
- `jiangling_mysql` —— MySQL 数据文件
## 修改后的生效方式
## 注意事项
- 修改 `.env` 后需重启 app 容器:`docker compose -f docker-compose.local.yml restart app`
- 修改源码后需重新构建:`docker compose -f docker-compose.local.yml up -d --build app`
- 此本地配置仅供开发/测试,**不要用于生产**(密码弱、APP_DEBUG=true)
- PHP、配置、模块、页面模板和路由目录已经挂载到容器,通常清理缓存或重启应用即可;
- Composer 依赖、前端依赖、Dockerfile 或构建资源发生变化时,重新执行 `bash deploy/local-init.sh`;
- 修改 `runtime/.env` 后,执行:
## 重要:DB_PREFIX 必须用短前缀
项目某个模块迁移创建了较长的唯一索引
(`ec_stores_company_id_channel_id_external_id_deleted_at_unique`,60 字符),
MySQL 标识符上限 64 字符,所以 `DB_PREFIX` 必须 ≤ 4 字符。本部署用 `a_`。
⚠️ **不要**让 `php artisan install` 自动生成前缀(它默认用 `str_random(3) . '_'` 是 4 字符,
刚好不超),但**首次 install 必须显式传 `--db-prefix=a_`** 或其他 ≤4 字符值,
否则可能随机到 5+ 字符前缀触发 1059 错误。
## 重置数据(清空重来)
```bash
docker compose -f docker-compose.local.yml exec mysql \
mysql -uroot -prootpass -e "DROP DATABASE IF EXISTS akaunting; CREATE DATABASE akaunting CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
docker compose -f docker-compose.local.yml exec app php artisan install --no-interaction \
--db-host=mysql --db-name=akaunting \
--db-username=akaunting --db-password=akaunting123 \
--db-prefix=a_ \
--company-name="本地测试公司" --company-email=admin@company.com \
--admin-email=admin@company.com --admin-password=admin123 \
--locale=zh-CN
docker compose -f docker-compose.local.yml restart app
docker compose -f docker-compose.local.yml exec app php artisan optimize:clear
```
## 部署中遇到并已解决的问题(备忘)
1. **Docker Hub 国内访问**:daemon.json 配置 `https://docker.1ms.run` 镜像源
2. **containerd snapshotter 导致 binary 全 0 字节**:在 Docker Desktop 设置里关闭 `UseContainerdSnapshotter`,改用 overlay2
3. **apt 交互卡住**:Dockerfile 加 `DEBIAN_FRONTEND=noninteractive` + `/etc/apt/apt.conf.d/99force-conf`
4. **deb.debian.org 不稳**:Dockerfile 切到清华 Debian 镜像
5. **node-sass 需要 python/make/g++**:Dockerfile 补装 `python3 make g++`
6. **npm run prod OOM**:改用 `npm run dev` + `NODE_OPTIONS=--max-old-space-size=2048`
7. **ec_stores 索引名超长**:用 `--db-prefix=a_`(见上)
## 相关文档
- 团队规则:`AGENTS.md`
- 开发和正式发布:`docs/开发与部署SOP.md`
- 上游业务接入:`docs/ecommerce-finance-development.md`
真实密码、数据库连接串、Token、SSH 私钥和 `runtime/.env` 均不得提交到 Git。

View File

@ -1,62 +1,52 @@
# Akaunting™
# CaiWuXiTong 财务系统
[![Release](https://img.shields.io/github/v/release/akaunting/akaunting?label=release)](https://github.com/akaunting/akaunting/releases)
![Downloads](https://img.shields.io/github/downloads/akaunting/akaunting/total?label=downloads)
[![Tests](https://img.shields.io/github/actions/workflow/status/akaunting/akaunting/tests.yml?label=tests)](https://github.com/akaunting/akaunting/actions)
本项目基于 Akaunting 二次开发,包含统一系统设置、用户和侧边栏管理、多个只读云数据库来源,以及财务业务页面。
Online accounting software designed for small businesses and freelancers. Akaunting is built with modern technologies such as Laravel, VueJS, Tailwind, RESTful API etc. Thanks to its modular structure, Akaunting provides an awesome App Store for users and developers.
## 开发者快速开始
* [Home](https://akaunting.com) - The house of Akaunting
* [Forum](https://akaunting.com/forum) - Ask for support
* [Documentation](https://akaunting.com/hc/docs) - Learn how to use
* [Developer Portal](https://developer.akaunting.com) - Generate passive income
* [App Store](https://akaunting.com/apps) - Extend your Akaunting
## Requirements
* PHP 8.1 or higher
* Database (e.g.: MariaDB, MySQL, PostgreSQL, SQLite)
* Web Server (eg: Apache, Nginx, IIS)
* [Other libraries](https://akaunting.com/hc/docs/on-premise/requirements/)
## Framework
Akaunting uses [Laravel](http://laravel.com), the best existing PHP framework, as the foundation framework and [Module](https://github.com/akaunting/module) package for Apps.
## Installation
* Clone the repository: `git clone https://github.com/akaunting/akaunting.git`
* Install dependencies: `composer install ; npm install ; npm run dev`
* Install Akaunting:
1. 启动 Docker Desktop。
2. 在仓库根目录执行:
```bash
php artisan install --db-name="akaunting" --db-username="root" --db-password="pass" --admin-email="admin@company.com" --admin-password="123456"
bash deploy/local-init.sh
```
* Create sample data (optional): `php artisan sample-data:seed`
3. 打开 `http://127.0.0.1:18088`。
4. 首次使用脚本显示的本机临时账号登录。
5. 打开“系统设置 → 数据库管理 → 系统数据库”。
6. 填写负责人提供的财务系统配置数据库并点击“测试并保存”。
7. 使用系统数据库中属于自己的账号重新登录。
## Contributing
完成系统数据库配置后,用户、侧边栏、系统设置和云数据库登记会自动统一。不需要再次填写两个云数据库密码,也不要复制生产环境或其他开发者的 `APP_KEY`、`.env`。
Please, be very clear on your commit messages and Pull Requests, empty Pull Request messages may be rejected without reason.
完整步骤和排错说明见 [LOCAL_DEPLOY.md](LOCAL_DEPLOY.md)。
When contributing code to Akaunting, you must follow the PSR coding standards. The golden rule is: Imitate the existing Akaunting code.
## 数据库边界
Please note that this project is released with a [Contributor Code of Conduct](https://akaunting.com/conduct). *By participating in this project you agree to abide by its terms*.
- 本机 MySQL 只负责第一次启动和临时登录,不是团队业务数据源。
- 系统数据库统一保存应用用户、系统设置、侧边栏配置和云数据库连接记录。
- 云数据库属于只读上游,业务必须经过固定适配器、允许范围和本地快照读取。
- 系统数据库不代理 SQL Server 网络。每台开发机仍需具备到上游端点的网络连通性。
- 不得把数据库密码、连接串、生产 `APP_KEY`、Token、SSH 私钥或 `runtime/.env` 提交到 Git。
## Changelog
## 开发和发布
Please see [Releases](../../releases) for more information about what has changed recently.
- 团队协作与安全规则:[AGENTS.md](AGENTS.md)
- 本地测试环境:[LOCAL_DEPLOY.md](LOCAL_DEPLOY.md)
- 开发和正式部署:[docs/开发与部署SOP.md](docs/开发与部署SOP.md)
- 上游业务接入规范:[docs/ecommerce-finance-development.md](docs/ecommerce-finance-development.md)
- 视觉规范:[DESIGN.md](DESIGN.md)
## Security
正式发布只能使用已经合并的 `main`,并通过 `scripts/deploy-from-workstation.ps1` 在开发机构建提交 SHA 镜像。生产服务器只运行镜像,不执行源码构建。
Please review [our security policy](https://github.com/akaunting/akaunting/security/policy) on how to report security vulnerabilities.
## 技术基础
## Credits
- PHP 8.3
- Laravel
- Vue
- Apache
- MySQL / MariaDB
- Docker
- Akaunting
* [Denis Duliçi](https://github.com/denisdulici)
* [Cüneyt Şentürk](https://github.com/cuneytsenturk)
* [All Contributors](../../contributors)
## License
Akaunting is released under the [BSL license](LICENSE.txt).
上游 Akaunting 的版权和许可证信息见 [LICENSE.txt](LICENSE.txt)。

View File

@ -3,16 +3,17 @@
return [
/*
|--------------------------------------------------------------------------
| 上游数据库总开关
| 上游数据库本机回退配置
|--------------------------------------------------------------------------
|
| 默认关闭。只有网络白名单、只读账号和连接驱动全部确认后,才允许在
| 服务器的 runtime/.env 中开启。凭据不得写入本文件或 Git。
| 标准模式从系统数据库的 system_database_connections 读取完整配置。
| 下面的环境变量只用于隔离排错或尚未迁移的旧环境;只有显式开启
| UPSTREAM_LOCAL_CONFIG_ENABLED 后才会覆盖共享配置。凭据不得进 Git。
|
*/
'enabled' => filter_var(env('JIANSUN_ENABLED', false), FILTER_VALIDATE_BOOL),
// 生产首次启用时从小表范围开始;支持精确 scope、prefix.* 和 *。
// 仅作为本机回退范围;共享模式优先读取系统数据库中的 allowed_scopes。
'allowed_scopes' => array_values(array_filter(array_map(
'trim',
explode(',', (string) env('JIANSUN_ALLOWED_SCOPES', ''))

View File

@ -1,7 +1,16 @@
<?php
return [
// 默认关闭;不得把真实端点、数据库名、账号或密码写入 Git。
/*
|--------------------------------------------------------------------------
| 经营分析副本库本机回退配置
|--------------------------------------------------------------------------
|
| 标准模式从系统数据库读取完整配置。下面的环境变量只用于隔离排错
| 或尚未迁移的旧环境;只有显式开启 UPSTREAM_LOCAL_CONFIG_ENABLED
| 后才会覆盖共享配置。真实端点、账号和密码不得写入 Git。
|
*/
'enabled' => filter_var(env('OPERATIONS_REPLICA_ENABLED', false), FILTER_VALIDATE_BOOL),
'allowed_scopes' => array_values(array_filter(array_map(

View File

@ -83,8 +83,7 @@ if [ ! -f "$REMOTE_DIR/runtime/.env" ]; then
'SESSION_DRIVER=file' \
'QUEUE_CONNECTION=sync' \
'UPSTREAM_STORED_CONFIG_ENABLED=true' \
'JIANSUN_ENABLED=false' \
'JIANSUN_ALLOWED_SCOPES=' \
'UPSTREAM_LOCAL_CONFIG_ENABLED=false' \
'MARIADB_DATABASE=caiwu' \
'MARIADB_USER=caiwu' \
"MARIADB_PASSWORD=$LEGACY_DB_PASSWORD" \

View File

@ -1,60 +1,128 @@
#!/bin/bash
# =====================================================
# CaiWuXiTong 本地部署一键初始化脚本
# 用法:bash deploy/local-init.sh
# 前提:Docker Desktop 已启动
# =====================================================
set -e
#!/usr/bin/env bash
set -euo pipefail
cd "$(dirname "$0")/.."
compose_file="docker-compose.local.yml"
environment_file="runtime/.env"
bootstrap_email="local-bootstrap@caiwu.test"
bootstrap_password="LocalOnly-18088!"
echo "==> 工作目录: $(pwd)"
# 1. 构建并启动服务
echo ""
echo "==> [1/4] 构建镜像并启动容器(首次需要 5-15 分钟下载 PHP/MySQL 镜像并安装依赖)..."
docker compose -f docker-compose.local.yml up -d --build
if ! command -v docker >/dev/null 2>&1; then
echo "错误:未找到 Docker,请先启动 Docker Desktop。" >&2
exit 1
fi
# 2. 等待 MySQL 就绪
echo ""
echo "==> [2/4] 等待 MySQL 就绪..."
if ! docker version >/dev/null 2>&1; then
echo "错误:Docker 尚未就绪,请先启动 Docker Desktop。" >&2
exit 1
fi
if [ ! -f "$environment_file" ]; then
mkdir -p runtime
app_key="base64:$(head -c 32 /dev/urandom | base64 | tr -d '\r\n')"
cat > "$environment_file" <<EOF
APP_NAME=CaiWuXiTong
APP_ENV=local
APP_DEBUG=true
APP_URL=http://127.0.0.1:18088
APP_KEY=$app_key
APP_INSTALLED=false
APP_LOCALE=zh-CN
APP_FALLBACK_LOCALE=en-GB
APP_TIMEZONE=Asia/Shanghai
LOG_CHANNEL=stack
DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=akaunting
DB_USERNAME=akaunting
DB_PASSWORD=akaunting123
DB_PREFIX=ak_
CACHE_DRIVER=file
SESSION_DRIVER=file
QUEUE_CONNECTION=sync
UPSTREAM_STORED_CONFIG_ENABLED=true
UPSTREAM_LOCAL_CONFIG_ENABLED=false
EOF
chmod 600 "$environment_file" 2>/dev/null || true
echo "==> 已生成本机私有 runtime/.env(不会提交到 Git)。"
fi
echo "==> [1/4] 构建镜像并启动本地容器..."
docker compose -f "$compose_file" up -d --build
echo "==> [2/4] 等待临时 MySQL 就绪..."
mysql_ready=0
for i in $(seq 1 60); do
if docker compose -f docker-compose.local.yml exec -T mysql \
if docker compose -f "$compose_file" exec -T mysql \
mysqladmin ping -h 127.0.0.1 -u akaunting -pakaunting123 >/dev/null 2>&1; then
echo " MySQL 已就绪。"
mysql_ready=1
echo " 临时 MySQL 已就绪。"
break
fi
echo " 等待中... ($i/60)"
sleep 2
done
# 3. 初始化数据库与管理员账号(幂等:已安装会自动跳过)
echo ""
echo "==> [3/4] 执行 php artisan install 初始化数据库与管理员..."
docker compose -f docker-compose.local.yml exec -T app \
php artisan install --no-interaction \
--db-host=mysql \
--db-port=3306 \
--db-name=akaunting \
--db-username=akaunting \
--db-password=akaunting123 \
--company-name="本地测试公司" \
--company-email=admin@company.com \
--admin-email=admin@company.com \
--admin-password=admin123 \
--locale=zh-CN \
|| echo " (install 已执行过则忽略此错误)"
if [ "$mysql_ready" -ne 1 ]; then
echo "错误:临时 MySQL 未能在规定时间内启动。" >&2
exit 1
fi
# 4. 最终验证
echo ""
echo "==> [4/4] 验证访问..."
sleep 3
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:18088/auth/login || echo "000")
echo " http://127.0.0.1:18088/auth/login -> HTTP $HTTP_CODE"
db_host="$(sed -n 's/^DB_HOST=//p' "$environment_file" | tail -n 1 | tr -d '\r')"
app_installed="$(sed -n 's/^APP_INSTALLED=//p' "$environment_file" | tail -n 1 | tr '[:upper:]' '[:lower:]' | tr -d '\r')"
if [ "$db_host" = "mysql" ] && [ "$app_installed" != "true" ] && [ "$app_installed" != "1" ]; then
echo "==> [3/4] 初始化仅供首次登录使用的本机引导库..."
docker compose -f "$compose_file" exec -T app \
php artisan install --no-interaction \
--db-host=mysql \
--db-port=3306 \
--db-name=akaunting \
--db-username=akaunting \
--db-password=akaunting123 \
--db-prefix=ak_ \
--company-name="本地引导环境" \
--company-email="$bootstrap_email" \
--admin-email="$bootstrap_email" \
--admin-password="$bootstrap_password" \
--locale=zh-CN
else
echo "==> [3/4] 当前环境已经初始化,跳过本机引导库安装。"
fi
echo "==> [4/4] 验证登录页..."
http_code="$(curl -sS -o /dev/null -w '%{http_code}' --max-time 15 \
http://127.0.0.1:18088/auth/login || true)"
if [ "$http_code" != "200" ]; then
echo "错误:登录页返回 HTTP ${http_code:-000},请运行以下命令查看日志:" >&2
echo "docker compose -f $compose_file logs --tail=100 app" >&2
exit 1
fi
echo ""
echo "====================================================="
echo "部署完成!"
echo " 访问地址: http://127.0.0.1:18088"
echo " 登录账号: admin@company.com"
echo " 登录密码: admin123"
echo "本地测试环境已启动:http://127.0.0.1:18088"
db_host="$(sed -n 's/^DB_HOST=//p' "$environment_file" | tail -n 1 | tr -d '\r')"
if [ "$db_host" = "mysql" ]; then
echo "首次临时账号:$bootstrap_email"
echo "首次临时密码:$bootstrap_password"
echo ""
echo "下一步:登录后打开“系统设置 → 数据库管理 → 系统数据库”,"
echo "填写负责人提供的财务系统配置数据库并点击“测试并保存”。"
echo "保存后两个云数据库会自动加载;不要复制 APP_KEY 或填写上游密码。"
else
echo "已检测到系统数据库配置,请使用系统数据库中属于自己的账号登录。"
fi
echo "====================================================="

View File

@ -1,12 +1,13 @@
# 本地开发/部署用 Compose 文件
# - 基于 compose.jiangling.yml 改造
# - 新增 mysql 服务(原文件依赖宿主机 MySQL)
# - 改用 bridge 网络替代 host 模式,便于本机访问
# 本地开发/测试用 Compose 文件
# - app 通过 runtime/.env 读取当前系统数据库配置
# - mysql 只用于首次登录和填写“系统数据库”前的临时引导
# - 保存系统数据库后,用户、设置和云数据库登记都来自共享系统数据库
#
# 启动: docker compose -f docker-compose.local.yml up -d --build
# 首次启动:bash deploy/local-init.sh
# 停止: docker compose -f docker-compose.local.yml down
# 日志: docker compose -f docker-compose.local.yml logs -f app
# 初始化:docker compose -f docker-compose.local.yml exec app php artisan install --db-host=mysql --db-name=akaunting --db-username=akaunting --db-password=akaunting123 --admin-email=admin@company.com --admin-password=admin123 --locale=zh-CN
#
# 不要把生产 APP_KEY、其他开发者的 .env 或云数据库密码复制到本机。
services:
app:
@ -20,7 +21,7 @@ services:
mysql:
condition: service_healthy
ports:
- "18088:18088"
- "127.0.0.1:18088:18088"
volumes:
- ./runtime/.env:/var/www/html/.env
- jiangling_storage:/var/www/html/storage
@ -43,6 +44,7 @@ services:
image: mysql:8.0
container_name: jiangling_mysql
restart: unless-stopped
# 这些凭据只属于回环地址上的临时引导库,不是团队共享数据库凭据。
environment:
MYSQL_ROOT_PASSWORD: rootpass
MYSQL_DATABASE: akaunting
@ -55,7 +57,7 @@ services:
volumes:
- jiangling_mysql:/var/lib/mysql
ports:
- "13306:3306"
- "127.0.0.1:13306:3306"
networks:
- jiangling_net
healthcheck:

View File

@ -192,19 +192,20 @@ php artisan upstream:snapshots:refresh <source_key>
相关 API 使用 `X-Caiwu-Data-Status`(`fresh` / `stale`)和 `X-Caiwu-Data-Synced-At` 响应头报告数据状态,验收时不能只看 HTTP 200。
旧的环境变量连接方式只用于迁移或紧急回滚;日常由超级管理员或普通管理员在“数据库管理”的“云数据库”区域维护,并加密保存到系统数据库。系统数据库连接在同页的独立区域维护,不得与云数据库记录混用。生产服务器私有 `runtime/.env` 至少保留下列开关和非敏感保护参数,真实值不得写入 Git 或本文档:
旧的环境变量连接方式只用于迁移、隔离排错或紧急回滚;日常由超级管理员或普通管理员在“数据库管理”的“云数据库”区域维护,并加密保存到系统数据库。系统数据库连接在同页的独立区域维护,不得与云数据库记录混用。
正常共享模式只要求生产服务器私有 `runtime/.env` 明确保留以下开关:
```dotenv
UPSTREAM_STORED_CONFIG_ENABLED=true
UPSTREAM_LOCAL_CONFIG_ENABLED=false
JIANSUN_ENABLED=false
JIANSUN_ALLOWED_SCOPES=
DB_JIANSUN_HOST=
DB_JIANSUN_PORT=1433
DB_JIANSUN_DATABASE=
DB_JIANSUN_USERNAME=
DB_JIANSUN_PASSWORD=
DB_JIANSUN_ODBC_DRIVER=FreeTDS
```
来源的启用状态、允许范围、地址、数据库名、账号和共享密码全部从系统数据库读取。正常共享模式不要在开发机或生产 `runtime/.env` 中填写 `DB_JIANSUN_*`、`DB_OPERATIONS_REPLICA_*` 或对应的 `*_ENABLED`。
下列参数是不含凭据的快照和保护参数,可以按来源保留在私有 `runtime/.env`;示例只展示 `jiansun`,其他来源使用自己的前缀:
```dotenv
JIANSUN_SNAPSHOT_TTL=120
JIANSUN_SUMMARY_TTL=120
JIANSUN_OPTIONS_TTL=3600
@ -220,6 +221,8 @@ JIANSUN_SLOW_QUERY_MS=5000
JIANSUN_SLOW_QUERY_COOLDOWN=300
```
只有明确进入本机覆盖模式时,才设置 `UPSTREAM_LOCAL_CONFIG_ENABLED=true`,并在私有 `runtime/.env` 中完整提供对应来源的 `DB_<来源>_*`、`<来源>_ENABLED` 和 `<来源>_ALLOWED_SCOPES`。覆盖模式不得作为团队日常开发方案。
开发机完成系统数据库配置后,系统自动设置 `UPSTREAM_STORED_CONFIG_ENABLED=true` 和 `UPSTREAM_LOCAL_CONFIG_ENABLED=false`,连接名称、地址、数据库名、账号、允许范围和共享密码均从系统数据库读取。不同开发机可以使用不同 `APP_KEY`,不得复制生产 `APP_KEY`。
完成上述配置后,不得再把主业务连接的 `DB_HOST` 改回本机 MySQL 容器。系统用户、侧边栏、系统设置和云数据库登记都属于同一套系统数据库数据;切回本机 MySQL 会形成一套独立数据,页面可能仍可登录,但用户数量、连接名称、来源映射和业务结果都可能与其他开发机不同。标准来源映射固定为:`jiansun` 对应 `JianSun` 旧业务库,`operations_replica` 对应 `JSReportReplica` 的 `rpt` 只读视图。系统数据库负责统一保存连接配置,不代理网络流量;每台开发机仍由自己的应用容器直接连接上游。