通过 Docker 的 Liquibase - 更新日志未写入磁盘
Liquibase via Docker - Changelog is not written to disk
我想在本地(而不是在容器中)为 PostgreSQL 数据库 运行 设置 Liquibase(使用 Docker)。我遵循了多个教程,包括 Docker Hub.
上的教程
按照建议,我在 <PATH TO CHANGELOG DIR>
中创建了一个 liquibase.docker.properties
文件
classpath: /liquibase/changelog
url: jdbc:postgresql://localhost:5432/mydb?currentSchema=public
changeLogFile: changelog.xml
username: myuser
password: mypass
能够运行docker run --rm --net="host" -v <PATH TO CHANGELOG DIR>:/liquibase/changelog liquibase/liquibase --defaultsFile=/liquibase/changelog/liquibase.docker.properties <COMMAND>
.
当我 运行 [...] generateChangeLog
我得到以下输出(带有选项 --logLevel info
):
[2021-04-27 06:08:20] INFO [liquibase.integration] No Liquibase Pro license key supplied. Please set liquibaseProLicenseKey on command line or in liquibase.properties to use Liquibase Pro features.
Liquibase Community 4.3.3 by Datical
####################################################
## _ _ _ _ ##
## | | (_) (_) | ##
## | | _ __ _ _ _ _| |__ __ _ ___ ___ ##
## | | | |/ _` | | | | | '_ \ / _` / __|/ _ \ ##
## | |___| | (_| | |_| | | |_) | (_| \__ \ __/ ##
## \_____/_|\__, |\__,_|_|_.__/ \__,_|___/\___| ##
## | | ##
## |_| ##
## ##
## Get documentation at docs.liquibase.com ##
## Get certified courses at learn.liquibase.com ##
## Free schema change activity reports at ##
## https://hub.liquibase.com ##
## ##
####################################################
Starting Liquibase at 06:08:20 (version 4.3.3 #52 built at 2021-04-12 17:08+0000)
BEST PRACTICE: The changelog generated by diffChangeLog/generateChangeLog should be inspected for correctness and completeness before being deployed.
[2021-04-27 06:08:22] INFO [liquibase.diff] changeSets count: 1
[2021-04-27 06:08:22] INFO [liquibase.diff] changelog.xml does not exist, creating and adding 1 changesets.
Liquibase command 'generateChangeLog' was executed successfully.
它看起来像命令 运行“成功”,但是 我在我挂载的本地目录 中找不到文件 changelog.xml
,即 <PATH TO CHANGELOG DIR>
。但是安装必须正常工作,因为它成功连接到数据库,即容器能够访问和读取 liquibase.docker.properties
.
首先我想我可能不得不“说”Docker允许它写入我的磁盘但似乎应该支持[根据Docker集线器上的描述] :
The /liquibase/changelog volume can also be used for commands that write output, such as generateChangeLog
我错过了什么?在此先感谢您的帮助!
附加信息
docker inspect
的输出:
"Mounts": [
{
"Type": "bind",
"Source": "<PATH TO CHANGELOG DIR>",
"Destination": "/liquibase/changelog",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
},
...
],
TL;DR
在变更日志文件名前加上/liquibase/changelog/
前缀并将其作为命令行参数传递:
[...] --changeLogFile /liquibase/changelog/changelog.xml generateChangelog
有关详细信息,请参阅 。
说明
我用 -it
启动了容器并覆盖了入口点以在容器内获得交互式 shell(参见 this post):
docker run --net="host" -v <PATH TO CHANGELOG DIR>:/liquibase/changelog -it --entrypoint /bin/bash liquibase/liquibase -s
执行 ls
产生以下结果:
liquibase@ubuntu-rafael:/liquibase$ ls
ABOUT.txt UNINSTALL.txt docker-entrypoint.sh liquibase
GETTING_STARTED.txt changelog examples liquibase.bat
LICENSE.txt changelog.txt lib liquibase.docker.properties
README.txt classpath licenses liquibase.jar
这里值得注意的是 docker-entrypoint.sh
,它实际执行了 liquibase 命令,文件夹 changelog
挂载到我的本地 <PATH TO CHANGELOG DIR>
(我的 .properties
文件在那里).
现在我 运行 使用与以前相同的命令,但现在 在 容器内:
sh docker-entrypoint.sh --defaultsFile=/liquibase/changelog/liquibase.docker.properties --logLevel info generateChangeLog
我得到了与上面相同的输出,但猜猜当 运行 ls
再次出现时会显示什么:
ABOUT.txt changelog examples liquibase.docker.properties
GETTING_STARTED.txt changelog.txt lib liquibase.jar
LICENSE.txt changelog.xml ...
更新日志确实存在!但是它是在错误的目录中创建的...
如果您在变更日志文件名前加上 /liquibase/changelog/
,容器能够将其写入您的本地(已安装)磁盘。
P.S。这意味着使用 here is not working. I will open an Issue 中的“属性文件”对“完整示例”的描述。
更新
只有写入新文件的命令才需要指定绝对路径,例如generateChangeLog
(参见 )。但更好的做法是通过命令行传递绝对路径,以便您可以将设置保留在默认文件中。
当您 运行 generateChangeLog
时,文件路径应指定为 /liquibase/changelog/changelog.xml
,即使 update
需要指定为 changelog.xml
示例:
docker run --rm --net="host" -v <PATH TO CHANGELOG DIR>:/liquibase/changelog liquibase/liquibase --defaultsFile=/liquibase/changelog/liquibase.docker.properties --changeLogFile=/liquibase/changelog/changelog.xml generateChangeLog
对于 generateChangeLog
,changeLogFile 参数是要输出的文件的特定路径,相对于更新和其他命令使用的 classpath
设置的路径。
当您像上面那样包含命令行参数和 defaultsFile 时,命令行参数会胜出。这让您可以利用相同的默认设置,同时在特定命令需要 more/different 时替换特定设置。
详情
创建文件的操作和读取现有文件的操作之间存在区别。
使用 Liquibase,您几乎总是希望使用与类路径中的目录相关的文件路径,就像示例中那样。指定的 changelogFile 存储在跟踪系统中,因此如果您 运行 相同的 changelog 但以不同的方式引用(因为您移动了根目录或 运行 从不同的机器)然后 Liquibase会将其视为一个新文件并尝试重新 运行 已经 运行 变更集。
这就是文档具有 classpath: /liquibase/changelog
和 changeLogFile: com/example/changelog.xml
的原因。 update
操作在 /liquibase/changelog 目录中查找名为 com/example/changelog.xml
的文件并找到它并将路径存储为 com/example/changelog.xml
.
GenerateChangeLog 是“并不总是相对于类路径”的情况之一,因为它需要知道将文件存储在何处。如果您只是将输出 changeLogFile 指定为 changelog.xml
,它只会创建相对于您进程的工作目录的文件,这不是您 needing/expecting.
我想在本地(而不是在容器中)为 PostgreSQL 数据库 运行 设置 Liquibase(使用 Docker)。我遵循了多个教程,包括 Docker Hub.
上的教程按照建议,我在 <PATH TO CHANGELOG DIR>
liquibase.docker.properties
文件
classpath: /liquibase/changelog
url: jdbc:postgresql://localhost:5432/mydb?currentSchema=public
changeLogFile: changelog.xml
username: myuser
password: mypass
能够运行docker run --rm --net="host" -v <PATH TO CHANGELOG DIR>:/liquibase/changelog liquibase/liquibase --defaultsFile=/liquibase/changelog/liquibase.docker.properties <COMMAND>
.
当我 运行 [...] generateChangeLog
我得到以下输出(带有选项 --logLevel info
):
[2021-04-27 06:08:20] INFO [liquibase.integration] No Liquibase Pro license key supplied. Please set liquibaseProLicenseKey on command line or in liquibase.properties to use Liquibase Pro features.
Liquibase Community 4.3.3 by Datical
####################################################
## _ _ _ _ ##
## | | (_) (_) | ##
## | | _ __ _ _ _ _| |__ __ _ ___ ___ ##
## | | | |/ _` | | | | | '_ \ / _` / __|/ _ \ ##
## | |___| | (_| | |_| | | |_) | (_| \__ \ __/ ##
## \_____/_|\__, |\__,_|_|_.__/ \__,_|___/\___| ##
## | | ##
## |_| ##
## ##
## Get documentation at docs.liquibase.com ##
## Get certified courses at learn.liquibase.com ##
## Free schema change activity reports at ##
## https://hub.liquibase.com ##
## ##
####################################################
Starting Liquibase at 06:08:20 (version 4.3.3 #52 built at 2021-04-12 17:08+0000)
BEST PRACTICE: The changelog generated by diffChangeLog/generateChangeLog should be inspected for correctness and completeness before being deployed.
[2021-04-27 06:08:22] INFO [liquibase.diff] changeSets count: 1
[2021-04-27 06:08:22] INFO [liquibase.diff] changelog.xml does not exist, creating and adding 1 changesets.
Liquibase command 'generateChangeLog' was executed successfully.
它看起来像命令 运行“成功”,但是 我在我挂载的本地目录 中找不到文件 changelog.xml
,即 <PATH TO CHANGELOG DIR>
。但是安装必须正常工作,因为它成功连接到数据库,即容器能够访问和读取 liquibase.docker.properties
.
首先我想我可能不得不“说”Docker允许它写入我的磁盘但似乎应该支持[根据Docker集线器上的描述] :
The /liquibase/changelog volume can also be used for commands that write output, such as generateChangeLog
我错过了什么?在此先感谢您的帮助!
附加信息
docker inspect
的输出:
"Mounts": [
{
"Type": "bind",
"Source": "<PATH TO CHANGELOG DIR>",
"Destination": "/liquibase/changelog",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
},
...
],
TL;DR
在变更日志文件名前加上/liquibase/changelog/
前缀并将其作为命令行参数传递:
[...] --changeLogFile /liquibase/changelog/changelog.xml generateChangelog
有关详细信息,请参阅
说明
我用 -it
启动了容器并覆盖了入口点以在容器内获得交互式 shell(参见 this post):
docker run --net="host" -v <PATH TO CHANGELOG DIR>:/liquibase/changelog -it --entrypoint /bin/bash liquibase/liquibase -s
执行 ls
产生以下结果:
liquibase@ubuntu-rafael:/liquibase$ ls
ABOUT.txt UNINSTALL.txt docker-entrypoint.sh liquibase
GETTING_STARTED.txt changelog examples liquibase.bat
LICENSE.txt changelog.txt lib liquibase.docker.properties
README.txt classpath licenses liquibase.jar
这里值得注意的是 docker-entrypoint.sh
,它实际执行了 liquibase 命令,文件夹 changelog
挂载到我的本地 <PATH TO CHANGELOG DIR>
(我的 .properties
文件在那里).
现在我 运行 使用与以前相同的命令,但现在 在 容器内:
sh docker-entrypoint.sh --defaultsFile=/liquibase/changelog/liquibase.docker.properties --logLevel info generateChangeLog
我得到了与上面相同的输出,但猜猜当 运行 ls
再次出现时会显示什么:
ABOUT.txt changelog examples liquibase.docker.properties
GETTING_STARTED.txt changelog.txt lib liquibase.jar
LICENSE.txt changelog.xml ...
更新日志确实存在!但是它是在错误的目录中创建的...
如果您在变更日志文件名前加上 /liquibase/changelog/
,容器能够将其写入您的本地(已安装)磁盘。
P.S。这意味着使用 here is not working. I will open an Issue 中的“属性文件”对“完整示例”的描述。
更新
只有写入新文件的命令才需要指定绝对路径,例如generateChangeLog
(参见
当您 运行 generateChangeLog
时,文件路径应指定为 /liquibase/changelog/changelog.xml
,即使 update
需要指定为 changelog.xml
示例:
docker run --rm --net="host" -v <PATH TO CHANGELOG DIR>:/liquibase/changelog liquibase/liquibase --defaultsFile=/liquibase/changelog/liquibase.docker.properties --changeLogFile=/liquibase/changelog/changelog.xml generateChangeLog
对于 generateChangeLog
,changeLogFile 参数是要输出的文件的特定路径,相对于更新和其他命令使用的 classpath
设置的路径。
当您像上面那样包含命令行参数和 defaultsFile 时,命令行参数会胜出。这让您可以利用相同的默认设置,同时在特定命令需要 more/different 时替换特定设置。
详情
创建文件的操作和读取现有文件的操作之间存在区别。
使用 Liquibase,您几乎总是希望使用与类路径中的目录相关的文件路径,就像示例中那样。指定的 changelogFile 存储在跟踪系统中,因此如果您 运行 相同的 changelog 但以不同的方式引用(因为您移动了根目录或 运行 从不同的机器)然后 Liquibase会将其视为一个新文件并尝试重新 运行 已经 运行 变更集。
这就是文档具有 classpath: /liquibase/changelog
和 changeLogFile: com/example/changelog.xml
的原因。 update
操作在 /liquibase/changelog 目录中查找名为 com/example/changelog.xml
的文件并找到它并将路径存储为 com/example/changelog.xml
.
GenerateChangeLog 是“并不总是相对于类路径”的情况之一,因为它需要知道将文件存储在何处。如果您只是将输出 changeLogFile 指定为 changelog.xml
,它只会创建相对于您进程的工作目录的文件,这不是您 needing/expecting.