feat: 一键部署——配置内置默认值,去掉示例复制与环境变量

目标:git clone 后 docker compose up -d 直接可用,无需任何手工准备。

变更:
- config.example/ → config/,config.example.yaml → config.yaml
  不再需要 cp -r 与逐份修改
- 删除 .env / .env.example,值全部内置到 docker-compose.yml
  (GoFrame 不展开配置文件中的 ${VAR},环境变量方案在 Go 侧不可用)
- 配置文件里的 ${VAR} 全部替换为字面默认值
- schema/04-users.sh 与 05-reset-passwords.sh 改为脚本内字面口令,
  不再读取环境变量
- 新增 schema/13-seed-flow-package.sql 占位文件,说明套餐表为空的原因与补齐方式
- .gitignore 不再排除 config/ 与 .env(已无 .env)
- README 改为「一键启动」+「上线前必改」两张表

已验证:docker compose config 通过;compose 口令、各配置文件 DSN、
初始化脚本三处口令哈希一致;库名与 schema 中一致。
This commit is contained in:
MiFaZhan
2026-10-29 09:17:26 +08:00
parent 0bfc0ebe80
commit 5ddad0c5e5
18 changed files with 252 additions and 299 deletions
+58 -59
View File
@@ -18,17 +18,16 @@ name: iotlcm
services:
# ---------------- 基础组件 ----------------
mysql:
image: '${REGISTRY:-your-registry}/library/mysql:8.0'
# 基础组件统走同一镜像仓库(`<REGISTRY>/library/`),版本在 .env 里固定
image: 'crpi-qflrqrxoohllkvgc.cn-chengdu.personal.cr.aliyuncs.com/library/mysql:8.0'
container_name: iotlcm-mysql
restart: always
ports:
- "${MYSQL_PORT:-3306}:3306"
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: '${MYSQL_ROOT_PASSWORD:?必须在 .env 中设置}'
MYSQL_DATABASE: '${MYSQL_DATABASE:-db_iotlcm}'
MYSQL_APP_PASSWORD: '${MYSQL_APP_PASSWORD:?必须在 .env 中设置}'
MYSQL_ADMIN_PASSWORD: '${MYSQL_ADMIN_PASSWORD:?必须在 .env 中设置}'
TZ: '${TZ:-Asia/Shanghai}'
MYSQL_ROOT_PASSWORD: 'Iotlcm2026Default'
MYSQL_DATABASE: 'db_iotlcm'
TZ: 'Asia/Shanghai'
volumes:
- ./data/mysql:/var/lib/mysql
# 仅在 data/mysql 为空(首次启动)时执行,按文件名顺序
@@ -40,24 +39,24 @@ services:
networks:
- iotlcm-network
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "-p${MYSQL_ROOT_PASSWORD}"]
test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "-piotlcm_root_2026"]
interval: 10s
timeout: 5s
retries: 10
start_period: 40s
redis:
image: '${REGISTRY:-your-registry}/library/redis:7.2'
image: 'crpi-qflrqrxoohllkvgc.cn-chengdu.personal.cr.aliyuncs.com/library/redis:7.2'
container_name: iotlcm-redis
restart: always
ports:
- "${REDIS_PORT:-6379}:6379"
- "6379:6379"
environment:
TZ: '${TZ:-Asia/Shanghai}'
TZ: 'Asia/Shanghai'
command:
- redis-server
- --requirepass
- '${REDIS_PASSWORD:?必须在 .env 中设置}'
- 'Iotlcm2026Default'
- --appendonly
- "yes"
volumes:
@@ -65,23 +64,23 @@ services:
networks:
- iotlcm-network
healthcheck:
test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD}", "ping"]
test: ["CMD", "redis-cli", "-a", "Iotlcm2026Default", "ping"]
interval: 10s
timeout: 5s
retries: 5
rabbitmq:
image: '${REGISTRY:-your-registry}/library/rabbitmq:4.3.5-management'
image: 'crpi-qflrqrxoohllkvgc.cn-chengdu.personal.cr.aliyuncs.com/library/rabbitmq:4.3.5-management'
container_name: iotlcm-rabbitmq
hostname: rabbitmq
restart: always
ports:
- "${RABBITMQ_PORT:-5672}:5672"
- "${RABBITMQ_MGMT_PORT:-15672}:15672"
- "5672:5672"
- "15672:15672"
environment:
RABBITMQ_DEFAULT_USER: '${RABBITMQ_USER:-iotlcm}'
RABBITMQ_DEFAULT_PASS: '${RABBITMQ_PASSWORD:?必须在 .env 中设置}'
TZ: '${TZ:-Asia/Shanghai}'
RABBITMQ_DEFAULT_USER: 'iotlcm'
RABBITMQ_DEFAULT_PASS: 'Iotlcm2026Default'
TZ: 'Asia/Shanghai'
volumes:
- ./data/rabbitmq:/var/lib/rabbitmq
networks:
@@ -94,13 +93,13 @@ services:
start_period: 30s
consul:
image: '${REGISTRY:-your-registry}/library/consul:1.22'
image: 'crpi-qflrqrxoohllkvgc.cn-chengdu.personal.cr.aliyuncs.com/library/consul:1.22'
container_name: iotlcm-consul
restart: always
ports:
- "${CONSUL_PORT:-8500}:8500"
- "8500:8500"
environment:
TZ: '${TZ:-Asia/Shanghai}'
TZ: 'Asia/Shanghai'
CONSUL_LOCAL_CONFIG: |
{
"node_name": "iotlcm-node",
@@ -120,13 +119,13 @@ services:
# ---------------- 业务服务 ----------------
admin-svr:
image: '${REGISTRY:-your-registry}/iotlcm/iotlcm-admin-svr:${TAG:-latest}'
image: 'crpi-qflrqrxoohllkvgc.cn-chengdu.personal.cr.aliyuncs.com/iotlcm/iotlcm-admin-svr:latest'
container_name: iotlcm-admin-svr
restart: always
ports:
- "127.0.0.1:${ADMIN_SVR_PORT:-8008}:8008"
- "127.0.0.1:8008:8008"
environment:
TZ: '${TZ:-Asia/Shanghai}'
TZ: 'Asia/Shanghai'
volumes:
- ./config/admin-svr:/app/config:ro
- ./data/logs/admin-svr:/app/logs
@@ -143,13 +142,13 @@ services:
condition: service_healthy
admin-ui:
image: '${REGISTRY:-your-registry}/iotlcm/iotlcm-admin-ui:${TAG:-latest}'
image: 'crpi-qflrqrxoohllkvgc.cn-chengdu.personal.cr.aliyuncs.com/iotlcm/iotlcm-admin-ui:latest'
container_name: iotlcm-admin-ui
restart: always
ports:
- "127.0.0.1:${ADMIN_UI_PORT:-8009}:80"
- "127.0.0.1:8009:80"
environment:
TZ: '${TZ:-Asia/Shanghai}'
TZ: 'Asia/Shanghai'
volumes:
- ./config/admin-ui/default.conf:/etc/nginx/conf.d/default.conf:ro
- ./data/logs/admin-ui:/var/log/nginx
@@ -160,13 +159,13 @@ services:
- admin-svr
openapi:
image: '${REGISTRY:-your-registry}/iotlcm/iotlcm-openapi:${TAG:-latest}'
image: 'crpi-qflrqrxoohllkvgc.cn-chengdu.personal.cr.aliyuncs.com/iotlcm/iotlcm-openapi:latest'
container_name: iotlcm-openapi
restart: always
ports:
- "127.0.0.1:${OPENAPI_PORT:-8000}:8000"
- "127.0.0.1:8000:8000"
environment:
TZ: '${TZ:-Asia/Shanghai}'
TZ: 'Asia/Shanghai'
volumes:
- ./config/openapi:/app/config:ro
- ./data/logs/openapi:/app/logs
@@ -181,14 +180,14 @@ services:
condition: service_healthy
upstream-chan:
image: '${REGISTRY:-your-registry}/iotlcm/iotlcm-upstream-chan:${TAG:-latest}'
image: 'crpi-qflrqrxoohllkvgc.cn-chengdu.personal.cr.aliyuncs.com/iotlcm/iotlcm-upstream-chan:latest'
container_name: iotlcm-upstream-chan
restart: always
ports:
- "${CHAN_HTTP_PORT:-8110}:8110"
- "${CHAN_GRPC_PORT:-8310}:8310"
- "8110:8110"
- "8310:8310"
environment:
TZ: '${TZ:-Asia/Shanghai}'
TZ: 'Asia/Shanghai'
volumes:
- ./config/upstream-chan:/app/config:ro
- ./data/logs/upstream-chan:/app/logs
@@ -205,13 +204,13 @@ services:
condition: service_started
upstream-proxy:
image: '${REGISTRY:-your-registry}/iotlcm/iotlcm-upstream-proxy:${TAG:-latest}'
image: 'crpi-qflrqrxoohllkvgc.cn-chengdu.personal.cr.aliyuncs.com/iotlcm/iotlcm-upstream-proxy:latest'
container_name: iotlcm-upstream-proxy
restart: always
ports:
- "${PROXY_PORT:-8510}:8510"
- "8510:8510"
environment:
TZ: '${TZ:-Asia/Shanghai}'
TZ: 'Asia/Shanghai'
volumes:
- ./config/upstream-proxy:/app/config:ro
- ./data/logs/upstream-proxy:/app/logs
@@ -229,11 +228,11 @@ services:
condition: service_started
worker-svr:
image: '${REGISTRY:-your-registry}/iotlcm/iotlcm-worker-svr:${TAG:-latest}'
image: 'crpi-qflrqrxoohllkvgc.cn-chengdu.personal.cr.aliyuncs.com/iotlcm/iotlcm-worker-svr:latest'
container_name: iotlcm-worker-svr
restart: always
environment:
TZ: '${TZ:-Asia/Shanghai}'
TZ: 'Asia/Shanghai'
volumes:
- ./config/worker-svr:/app/config:ro
- ./data/logs/worker-svr:/app/logs
@@ -251,13 +250,13 @@ services:
condition: service_healthy
app-server:
image: '${REGISTRY:-your-registry}/iotlcm/iotlcm-app-server:${TAG:-latest}'
image: 'crpi-qflrqrxoohllkvgc.cn-chengdu.personal.cr.aliyuncs.com/iotlcm/iotlcm-app-server:latest'
container_name: iotlcm-app-server
restart: always
ports:
- "127.0.0.1:${APP_SERVER_PORT:-8010}:8010"
- "127.0.0.1:8010:8010"
environment:
TZ: '${TZ:-Asia/Shanghai}'
TZ: 'Asia/Shanghai'
APP_UPLOAD_DIR: /app/resource/upload
volumes:
- ./config/app-server:/app/config:ro
@@ -272,30 +271,30 @@ services:
condition: service_healthy
app-web:
image: '${REGISTRY:-your-registry}/iotlcm/iotlcm-app-web:${TAG:-latest}'
image: 'crpi-qflrqrxoohllkvgc.cn-chengdu.personal.cr.aliyuncs.com/iotlcm/iotlcm-app-web:latest'
container_name: iotlcm-app-web
restart: always
ports:
- "127.0.0.1:${APP_WEB_PORT:-8018}:80"
- "127.0.0.1:8018:80"
environment:
TZ: '${TZ:-Asia/Shanghai}'
TZ: 'Asia/Shanghai'
volumes:
- ./data/logs/app-web:/var/log/nginx
networks:
- iotlcm-network
sms:
image: '${REGISTRY:-your-registry}/iotlcm/iotlcm-sms:${TAG:-latest}'
image: 'crpi-qflrqrxoohllkvgc.cn-chengdu.personal.cr.aliyuncs.com/iotlcm/iotlcm-sms:latest'
container_name: iotlcm-sms
hostname: iotlcm-sms
restart: always
environment:
TZ: '${TZ:-Asia/Shanghai}'
TZ: 'Asia/Shanghai'
HTTP_ADDR: ':11190'
GRPC_ADDR: ':11200'
ports:
- "${SMS_HTTP_PORT:-11190}:11190"
- "${SMS_GRPC_PORT:-11200}:11200"
- "11190:11190"
- "11200:11200"
volumes:
- ./config/sms:/app/config:ro
- ./data/logs/sms:/app/logs
@@ -313,11 +312,11 @@ services:
- iotlcm-network
bot:
image: '${REGISTRY:-your-registry}/iotlcm/iotlcm-bot:${TAG:-latest}'
image: 'crpi-qflrqrxoohllkvgc.cn-chengdu.personal.cr.aliyuncs.com/iotlcm/iotlcm-bot:latest'
container_name: iotlcm-bot
restart: unless-stopped
environment:
TZ: '${TZ:-Asia/Shanghai}'
TZ: 'Asia/Shanghai'
command: ["watch", "--config", "/app/config/config.yaml"]
volumes:
- ./config/bot/config.yaml:/app/config/config.yaml:ro
@@ -329,11 +328,11 @@ services:
- with-bot
docs:
image: '${REGISTRY:-your-registry}/iotlcm/iotlcm-docs:${TAG:-latest}'
image: 'crpi-qflrqrxoohllkvgc.cn-chengdu.personal.cr.aliyuncs.com/iotlcm/iotlcm-docs:latest'
container_name: iotlcm-docs
restart: unless-stopped
ports:
- "127.0.0.1:${DOCS_PORT:-8019}:80"
- "127.0.0.1:8019:80"
networks:
- iotlcm-network
@@ -345,13 +344,13 @@ services:
# 启用后 upstream-chan 的 sim_yd_mock_v5.url 指向 http://onelink-mock:8080/v5/
# (config.example/upstream-chan 已预置该地址)
onelink-mock:
image: '${REGISTRY:-your-registry}/iotlcm/iotlcm-onelink-mock:${TAG:-latest}'
image: 'crpi-qflrqrxoohllkvgc.cn-chengdu.personal.cr.aliyuncs.com/iotlcm/iotlcm-onelink-mock:latest'
container_name: iotlcm-onelink-mock
restart: unless-stopped
ports:
- "127.0.0.1:${MOCK_PORT:-8080}:8080"
- "127.0.0.1:8080:8080"
environment:
TZ: '${TZ:-Asia/Shanghai}'
TZ: 'Asia/Shanghai'
BAFFLE_ADDR: ':8080'
BAFFLE_SQLITE_PATH: /app/data/onelink_mock.db
volumes:
@@ -372,11 +371,11 @@ services:
# 若宿主机已有 nginx / 面板,可不启动本容器,
# 参考 config.example/nginx/iotlcm.conf 把 location 段落到宿主机配置。
nginx:
image: '${REGISTRY:-your-registry}/library/nginx:1.30'
image: 'crpi-qflrqrxoohllkvgc.cn-chengdu.personal.cr.aliyuncs.com/library/nginx:1.30'
container_name: iotlcm-nginx
restart: always
ports:
- "${NGINX_HTTP_PORT:-80}:80"
- "80:80"
volumes:
- ./config/nginx:/etc/nginx/conf.d:ro
- ./data/logs/nginx:/var/log/nginx