Docker Compose部署Liquibase提示changelog.yaml不存在求助
问题:Liquibase在Docker Compose中执行报错“Missing required subcommand”
配置与错误信息
用户的Docker Compose配置如下:
version: '3' services: app: image: data-service:dev container_name: data-service environment: - MONGO_DB=mongodb://user:pass@mongodatab/careers - POSTGRES_DB=jdbc:postgresql://postgresdatab ports: - '8090:8090' command: '/bin/bash -c "sleep 5; mongosh $$MONGO_DB --eval \"show dbs;\""' depends_on: - mongodatab - liquibasePostgres mongodatab: image: mongodb/mongodb-community-server:6.0-ubi8 container_name: data-service-mongo ports: - '27017:27017' volumes: - type: bind source: ./../db target: /db/mongodb postgresdatab: image: postgres container_name: data-service-postgres restart: always environment: - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres ports: - '5432:5432' volumes: - ./data/postgres:/var/lib/postgresql/data liquibasePostgres: image: liquibase/liquibase:latest container_name: data-service-liquibasePostgres depends_on: - postgresdatab command: --url=jdbc:postgresql://postgresdatab:5432/postgres?user=postgres&password=postgres --changeLogFile=/liquibase/changelog/changelog.yaml update volumes: - ./liquibase/postgres/changelog.yaml:/liquibase/changelog/changelog.yaml volumes: db: driver: local
运行后liquibasePostgres服务抛出错误:
Starting Liquibase at 05:36:13 (version 4.23.2 #13458 built at 2023-09-11 22:00+0000) Liquibase Version: 4.23.2 [2023-09-13 05:36:13] INFO [liquibase.ui] Liquibase Version: 4.23.2 [2023-09-13 05:36:13] FINE [liquibase.configuration] No configuration value for liquibase.licenseKey found [2023-09-13 05:36:13] FINE [liquibase.configuration] No configuration value for liquibase.pro.licenseKey found Liquibase Open Source 4.23.2 by Liquibase [2023-09-13 05:36:13] INFO [liquibase.ui] Liquibase Open Source 4.23.2 by Liquibase [2023-09-13 05:36:13] FINE [liquibase.configuration] No configuration value for liquibase.monitorPerformance found [2023-09-13 05:36:13] FINE [liquibase.configuration] Configuration liquibase.monitorPerformance is using the default value of false [2023-09-13 05:36:13] FINE [liquibase.integration] Performance monitoring disabled [2023-09-13 05:36:13] FINE [liquibase.servicelocator] Loaded liquibase.logging.mdc.MdcManager instance liquibase.logging.mdc.NoOpMdcManager [2023-09-13 05:36:13] FINE [liquibase.servicelocator] Loaded liquibase.logging.mdc.MdcManager instance com.datical.liquibase.ext.logging.structured.StructuredMdcManager [2023-09-13 05:36:13] INFO [liquibase.integration] Starting command execution. **Missing required subcommand** Usage: liquibase [GLOBAL OPTIONS] [COMMAND] [COMMAND OPTIONS] Command-specific help: "liquibase <command-name> --help"
用户手动进入容器测试,确认changelog文件存在,但执行命令时仍报错:
liquibase --log-level=debug --url=jdbc:postgresql://postgresdatab/postgres?user=postgres&password=postgres --changeLogFile=/changelog/changelog.yaml update
错误信息:
[1] 11 bash: --changeLogFile=/changelog/changelog.yaml: No such file or directory liquibase@docker-desktop:/liquibase$ #################################################### ## _ _ _ _ ## ## | | (_) (_) | ## ## | | _ __ _ _ _ _| |__ __ _ ___ ___ ## ## | | | |/ _` | | | | | '_ \ / _` / __|/ _ \ ## ## | |___| | (_| | |_| | | |_) | (_| \__ \ __/ ## ## \_____/_|\__, |\__,_|_|_.__/ \__,_|___/\___| ## ## | | ## ## |_| ## ## ## ## Get documentation at docs.liquibase.com ## ## Get certified courses at learn.liquibase.com ## ## ## #################################################### Starting Liquibase at 05:47:39 (version 4.23.2 #13458 built at 2023-09-11 22:00+0000) Liquibase Version: 4.23.2 Liquibase Open Source 4.23.2 by Liquibase Missing required subcommand Usage: liquibase [GLOBAL OPTIONS] [COMMAND] [COMMAND OPTIONS] Command-specific help: "liquibase <command-name> --help"
错误原因
问题出在JDBC URL中的&符号被bash解析成了后台执行符,导致整个命令被拆分成两个独立部分:
liquibase --log-level=debug --url=jdbc:postgresql://postgresdatab/postgres?user=postgres被后台执行(对应输出中的[1] 11)- 剩余的
password=postgres --changeLogFile=/changelog/changelog.yaml update被bash当作新命令执行,自然提示找不到--changeLogFile命令;同时Liquibase进程因参数不完整,提示缺少子命令。
解决方案
1. 修正Docker Compose中的liquibasePostgres服务命令
推荐使用数组格式的command,彻底避免bash符号解析问题:
liquibasePostgres: image: liquibase/liquibase:latest container_name: data-service-liquibasePostgres depends_on: - postgresdatab command: - "--url=jdbc:postgresql://postgresdatab:5432/postgres?user=postgres&password=postgres" - "--changeLogFile=/liquibase/changelog/changelog.yaml" - "update" volumes: - ./liquibase/postgres/changelog.yaml:/liquibase/changelog/changelog.yaml
也可以用单引号包裹整个命令(注意YAML语法的转义):
command: 'liquibase --url=jdbc:postgresql://postgresdatab:5432/postgres?user=postgres&password=postgres --changeLogFile=/liquibase/changelog/changelog.yaml update'
2. 手动执行命令时的修正
在容器内手动执行时,需要用引号包裹URL参数,或者转义&符号:
# 方法1:用引号包裹完整URL liquibase --log-level=debug --url="jdbc:postgresql://postgresdatab/postgres?user=postgres&password=postgres" --changeLogFile=/liquibase/changelog/changelog.yaml update # 方法2:转义&符号 liquibase --log-level=debug --url=jdbc:postgresql://postgresdatab/postgres?user=postgres\&password=postgres --changeLogFile=/liquibase/changelog/changelog.yaml update
额外优化建议
可以将数据库连接参数通过环境变量传递,避免URL中明文暴露密码,同时彻底规避符号解析问题:
liquibasePostgres: image: liquibase/liquibase:latest container_name: data-service-liquibasePostgres depends_on: - postgresdatab environment: - LIQUIBASE_URL=jdbc:postgresql://postgresdatab:5432/postgres - LIQUIBASE_USER=postgres - LIQUIBASE_PASSWORD=postgres command: - "--changeLogFile=/liquibase/changelog/changelog.yaml" - "update" volumes: - ./liquibase/postgres/changelog.yaml:/liquibase/changelog/changelog.yaml
Liquibase会自动读取这些环境变量作为连接参数,更安全且无需处理特殊符号。
内容的提问来源于stack exchange,提问作者Miguel Jasso
相关产品推荐
相关产品推荐

